package hdmstore;

import java.util.ArrayList;

import uk.ac.bbk.dcs.automed.hdmstore.HdmWrapper;
import uk.ac.bbk.dcs.automed.hdmstore.HdmWrapperFactory;
import uk.ac.bbk.dcs.automed.qproc.iql.ASG;
import uk.ac.bbk.dcs.automed.qproc.iql.Cell;

public class DemoHdmWrapper
{

	public static void main(String[] args)
	{
		DemoHdmWrapper dhw = new DemoHdmWrapper();

		dhw.demoQueries(); 		// 'select' query demos
		dhw.demoNodeUpdates(); 	// updates and deletes on nodes
		dhw.demoEdgeUpdates(); 	// updates and deletes on edges
	}

	private void demoEdgeUpdates()
	{
		ArrayList arrayListOfCells;
		ArrayList arrayListOfArgs;
		ASG list, query, edgeArgs;
		Cell cellTupleLit,
			cellValue,
			cellTuple,
			cellApply,
			cellFunction,
			cellScheme,
			cellQuery;
		HdmWrapperFactory hwf;
		HdmWrapper wrap = null;
		boolean result;
		
		
		//	EDGE test <<worksIn,person,project>>

		// {dean,tristarp}
		arrayListOfCells = new ArrayList();
		arrayListOfArgs = new ArrayList();
		cellValue = new Cell("dean");
		arrayListOfArgs.add(cellValue);
		cellValue = new Cell("tristarp");
		arrayListOfArgs.add(cellValue);
		edgeArgs = ASG.toASGTuple(arrayListOfArgs);
		arrayListOfCells.add(edgeArgs.root());

		// {lucas, auotemed}
		arrayListOfArgs = new ArrayList();
		cellValue = new Cell("lucas");
		arrayListOfArgs.add(cellValue);
		cellValue = new Cell("automed");
		arrayListOfArgs.add(cellValue);
		edgeArgs = ASG.toASGTuple(arrayListOfArgs);
		arrayListOfCells.add(edgeArgs.root());

		//		[{dean,tristarp},{lucas, auotemed}]
		list = ASG.toASGList(arrayListOfCells);

		//		the function sub
		cellFunction = new Cell(Cell.function, "sub");

		// apply the function to the list
		cellApply = new Cell(cellFunction, list.root());

		// the scheme <<person>>
		cellScheme = new Cell(Cell.scheme, "<<worksIn,person,project>>");

		// root cell for the query
		cellQuery = new Cell(cellApply, cellScheme);

		// ASG query
		query = new ASG(cellQuery);

		// so this is the ASG I will pass to my wrapper
		System.out.println("\n\nEDGE UPDATES");
		System.out.println("============\n\n");
		System.out.println("edge update IQL is " + query.toString());

		hwf = new HdmWrapperFactory();
		try
		{
			wrap = hwf.build("personnel");
			result = wrap.deleteIQL(query);
			System.out.println("result of delete before edge insert is: " + result);
			System.out.println("database after edge delete: ");
			query("<<worksIn,person,project>>");
		}
		catch (Throwable t)
		{
			t.printStackTrace();
		}

		try
		{
			result = wrap.insertIQL(query);
			System.out.println("Result of insert is " + result);
			System.out.println("database after insert: ");
			query("<<worksIn,person,project>>");
		}
		catch (Throwable t)
		{
			t.printStackTrace();
		}

	}

	private void demoNodeUpdates()
	{

		ArrayList arrayListOfCells;
		ArrayList arrayListOfArgs;
		ASG list, query, edgeArgs;
		Cell cellTupleLit,
			cellValue,
			cellTuple,
			cellApply,
			cellFunction,
			cellScheme,
			cellQuery;
		HdmWrapperFactory hwf;
		HdmWrapper wrap = null;
		boolean result;

		// NODE Tests <<person>>

		arrayListOfCells = new ArrayList();

		// {dean}
		cellTupleLit = new Cell(Cell.constructor, "Tuple1");
		cellValue = new Cell("dean");
		cellTuple = new Cell(cellTupleLit, cellValue);
		arrayListOfCells.add(cellTuple);

		// {lucas}
		cellTupleLit = new Cell(Cell.constructor, "Tuple1");
		cellValue = new Cell("lucas");
		cellTuple = new Cell(cellTupleLit, cellValue);
		arrayListOfCells.add(cellTuple);

		// {hao}
		cellTupleLit = new Cell(Cell.constructor, "Tuple1");
		cellValue = new Cell("hao");
		cellTuple = new Cell(cellTupleLit, cellValue);
		arrayListOfCells.add(cellTuple);

		// [{dean},{lucas},{hao}]
		list = ASG.toASGList(arrayListOfCells);

		// the function sub
		cellFunction = new Cell(Cell.function, "sub");

		// apply the function to the list
		cellApply = new Cell(cellFunction, list.root());

		// the scheme <<person>>
		cellScheme = new Cell(Cell.scheme, "<<person>>");

		// root cell for the query
		cellQuery = new Cell(cellApply, cellScheme);

		// ASG query
		query = new ASG(cellQuery);
		
		hwf = new HdmWrapperFactory();

		System.out.println("\n\nNODE UPDATES");
		System.out.println("============\n\n");
		System.out.println("node update IQL is " + query.toString());
		
		try
		{
			wrap = hwf.build("personnel");
			result = wrap.insertIQL(query);
			System.out.println("result from insertIQL is " + result);
			System.out.println("database after insert: ");
			query("<<person>>");
		}
		catch (Throwable t)
		{
			t.printStackTrace();
		}
	}

	private void query(String qString)
	{
		ASG query, result;
		HdmWrapperFactory hwf;
		HdmWrapper wrap;

		hwf = new HdmWrapperFactory();

		try
		{
			wrap = hwf.build("personnel"); //schema name	
			query = new ASG(qString);
			result = wrap.executeIQL(query);
			System.out.println(ASG.fromASG(result));
		}
		catch (Throwable t)
		{
			t.printStackTrace();
		}
	}

	private void demoQueries()
	{
		System.out.println("INITIAL STATE OF THE DATABASE");
		System.out.println("=============================\n\n");
		System.out.println("Test Query 1 - <<person>>");
		query("<<person>>");

		System.out.println("\n\nTest Query 2 - <<worksIn,person,project>>");
		query("<<worksIn,person,project>>");

		System.out.println(
			"\n\nTest Query 3 - <<livesAt,person,<<address,houseNumber,road,town,postCode>>>>");
		query("<<livesAt,person,<<address,houseNumber,road,town,postCode>>>>");
	}

}
