package org.postgresforest.tool.tests;

import java.io.*;
import java.sql.*;
import junit.framework.*;

import org.postgresforest.tool.lib.Config;
import org.postgresforest.tool.lib.Database;
import org.postgresforest.tool.lib.Instance;
import org.postgresforest.tool.lib.Table;
import org.postgresforest.tool.lib.GSCdata;
import org.postgresforest.tool.lib.PartitionUtils;
import org.postgresforest.tool.lib.ForestToolException;

public class TestTable extends TestCase {
	String user = "snaga";
	String pass = "";

	public void setUp()
	{
	}

	public void tearDown()
	{
	}

	private boolean dropdb(String dbname, String portNumber)
	{
		boolean rc = false;

		try {
            Thread.sleep(2000);

			String url = "jdbc:postgresql://localhost:" + portNumber + "/postgres";
			System.out.println(url);

			Connection con = DriverManager.getConnection(url, user, pass);

			con.createStatement().executeUpdate("DROP DATABASE " + dbname);
			con.close();
			rc = true;

            Thread.sleep(2000);
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
		}

		return rc;
	}

    private boolean executeDDL(String dbName, String portNumber, String sql)
    {
        boolean rc = false;

        try {
            String url = "jdbc:postgresql://localhost:" + portNumber + "/" + dbName;

            Connection con = DriverManager.getConnection(url, user, pass);
            con.createStatement().executeUpdate(sql);
            con.close();
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
			return false;
        }

		return true;
    }


	public void testInitialize001()
	{
		GSCdata gsc = null;

		dropdb("gsctest", "9998");
		dropdb("testdb", "9998");
		dropdb("testdb", "9999");

		try {
			gsc = GSCdata.initialize("localhost", "9998", "gsctest",
									 user, pass);
			assertTrue(gsc!=null);

			gsc.registerInstance("localhost", "9999");

			Database d = gsc.createDatabase("testdb");

			d.createTable("CREATE TABLE t1 ( uid INTEGER PRIMARY KEY, name TEXT NOT NULL );CREATE INDEX t1_name_idx ON t1(name)");
			d.createTable("CREATE TABLE t2 ( uid2 INTEGER REFERENCES t1(uid), name2 TEXT NOT NULL )");

			String[] t = d.getTableNames();

			assertTrue( t[0].equals("t1") );
			assertTrue( t[1].equals("t2") );
			
			gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
		}
	}

	public void testGetConstraintDefs001()
	{
        GSCdata gsc = null;

		try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
							  user, pass);

            assertTrue(gsc!=null); 

            Database d = gsc.getDatabase("testdb");

            Table t1 = d.getTable("t1");
            Table t2 = d.getTable("t2");

			assertTrue(t1!=null);
			assertTrue(t2!=null);

			String[] defs = t1.getConstraintDefs();
			assertTrue( defs.length == 1 );
			assertTrue( defs[0].equals("ALTER TABLE public.t1 ADD CONSTRAINT t1_pkey PRIMARY KEY (uid);") );

			String[] defs2 = t2.getConstraintDefs();
			assertTrue( defs2.length == 1 );
			assertTrue( defs2[0].equals("ALTER TABLE public.t2 ADD CONSTRAINT t2_uid2_fkey FOREIGN KEY (uid2) REFERENCES t1(uid);") );

            gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
        }
	}

	public void testGetIndexDefs001()
	{
        GSCdata gsc = null;

		try {
            gsc = new GSCdata("localhost", "9998", "gsctest",
							  user, pass);

            assertTrue(gsc!=null); 

            Database d = gsc.getDatabase("testdb");

            Table t1 = d.getTable("t1");

			assertTrue(t1!=null);

			String[] defs = t1.getIndexDefs();
			assertTrue( defs.length == 1 );
			assertTrue( defs[0].equals("CREATE INDEX t1_name_idx ON t1 USING btree (name);") );

            gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
        }
	}

	public void testBuildRuleDef001()
    {
		String[] pkeys = { "uid" };
		String[] cols  = { "uid", "uname" };

		String defs = null;

		defs = PartitionUtils.buildUpdateRuleDef(3, "t1", pkeys, cols);
		System.out.println(defs);

		defs = PartitionUtils.buildDeleteRuleDef(3, "t1", pkeys);
		System.out.println(defs);
	}

	public void testBuildRuleDef002()
    {
		String[] pkeys = { "uid", "uname" };
		String[] cols  = { "uid", "uname" };

		String defs = null;

		defs = PartitionUtils.buildUpdateRuleDef(3, "t1", pkeys, cols);
		System.out.println(defs);

		defs = PartitionUtils.buildDeleteRuleDef(3, "t1", pkeys);
		System.out.println(defs);
	}

	public void testBuildIndexDefs001()
    {
		String[] indexDefs = { "CREATE UNIQUE INDEX t1_pkey ON t1 USING btree (uid);" };

		String[] partIndexDefs = PartitionUtils.buildIndexDefs(3, "t1", indexDefs);

		assertTrue( partIndexDefs.length==3 );
		assertTrue( partIndexDefs[0].equals("CREATE UNIQUE INDEX t1_pkey_00 ON t1_00 USING btree (uid);") );
		assertTrue( partIndexDefs[1].equals("CREATE UNIQUE INDEX t1_pkey_01 ON t1_01 USING btree (uid);") );
		assertTrue( partIndexDefs[2].equals("CREATE UNIQUE INDEX t1_pkey_02 ON t1_02 USING btree (uid);") );
	}

	public void testBuildPartitionDefs001()
    {
		String[] pkeys = { "uid" };
		String[] cols  = { "uid", "uname" };

		String defs = null;

		defs = PartitionUtils.buildPartitionDefs(3, "t1", pkeys, null);
		System.out.println(defs);
	}

	public void testBuildPartitionDefs002()
    {
		String[] pkeys = { "uid" };
		String[] cols  = { "uid", "uname" };

		String defs = null;

		defs = PartitionUtils.buildPartitionDefs(3, "t1", pkeys, null);
		defs = defs + PartitionUtils.buildUnionAllViewDef(3, "t1");
		defs = defs + PartitionUtils.buildUpdateRuleDef(3, "t1", pkeys, cols);
		defs = defs + PartitionUtils.buildDeleteRuleDef(3, "t1", pkeys);

		System.out.println(defs);
	}

	public void testPart001()
	{
		GSCdata gsc = null;

		try {
			gsc = new GSCdata("localhost", "9998", "gsctest",
							  user, pass);
			assertTrue(gsc!=null);

			Database d = gsc.getDatabase("testdb");

			d.createTable("CREATE TABLE t3 ( uid INTEGER PRIMARY KEY, name TEXT NOT NULL );CREATE INDEX t3_name_idx ON t3(name)");

			Table t = d.getTable("t3");

			String[] partKeys = { "uid" };

			t.part(partKeys, 3, null);

			gsc.close();
		}
		catch (ForestToolException e)
		{
			System.out.println(e.getMessage());
			fail();
		}
	}


	public static void main(String[] args)
	{
		try {
			Class.forName("org.postgresql.Driver");
		}
		catch (Exception e)
		{
			System.out.println(e.getMessage());
			System.exit(-1);
		}

		junit.textui.TestRunner.run(TestTable.class);
	}
}
