/*
 * Copyright (c) 2009-2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.tests.db.capabilities;

import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.IDBConnectionProvider;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import junit.framework.TestCase;

/**
 * This is a simple test case that can be used to analyze how a DBMS handles DML in the middle of a transaction.
 *
 * @author Stefan Winkler
 */
public abstract class AbstractCapabilityTest extends TestCase
{
  public AbstractCapabilityTest(String name)
  {
    super(name);
  }

  public void testDirtyRead() throws Exception
  {
    msg("TEST " + getClass().getSimpleName() + " - DIRTY READ");
    msg("----------------------------------------------------------");
    msg("Transaction 1 changes a value, transaction 2 will read the value.");
    msg("The value of transaction 2 should be UNCHANGED (else we have a dirty read)");

    Thread t = new Thread()
    {
      @Override
      public void run()
      {
        try
        {
          IDBConnectionProvider provider = getConnectionProvider();
          Connection transaction1 = provider.getConnection();
          transaction1.setAutoCommit(false);

          Statement tx1stmt = transaction1.createStatement();
          tx1stmt.executeUpdate("update status_table set status = 'changed' where trans = 'transaction1'");
          msg("Read value (transaction 1) is "
              + select(transaction1, "select status from status_table where trans = 'transaction1'").toUpperCase());
          sleep(1000);

          transaction1.rollback();
          transaction1.close();
        }
        catch (Exception e)
        {
          throw new Error(e);
        }
      }
    };

    t.start();
    Thread.sleep(300);

    IDBConnectionProvider provider = getConnectionProvider();
    Connection transaction2 = provider.getConnection();

    transaction2.setAutoCommit(false);

    msg("Read value (transaction 2) is "
        + select(transaction2, "select status from status_table where trans = 'transaction1'").toUpperCase());
    msg("----------------------------------------------------------");
    transaction2.rollback();
    transaction2.close();
  }

  public void testRollback() throws Exception
  {
    msg("TEST " + getClass().getSimpleName() + " - ROLLBACK");
    msg("----------------------------------------------------------");
    msg("Transaction changes a value and does a rollback.");
    msg("The value of after rollback should be UNCHANGED.");

    IDBConnectionProvider provider = getConnectionProvider();
    Connection transaction1 = provider.getConnection();
    transaction1.setAutoCommit(false);

    Statement tx1stmt = transaction1.createStatement();

    try
    {
      tx1stmt.executeUpdate("update status_table set status = 'changed' where trans = 'transaction1'");
    }
    finally
    {
      DBUtil.close(tx1stmt);
    }

    msg("Read value before rollback is "
        + select(transaction1, "select status from status_table where trans = 'transaction1'").toUpperCase());

    transaction1.rollback();
    transaction1.close();

    Connection view = provider.getConnection();
    msg("Read value after rollback is "
        + select(view, "select status from status_table where trans = 'transaction1'").toUpperCase());
    view.close();
    msg("----------------------------------------------------------");
  }

  public void testDml() throws Exception
  {
    msg("TEST " + getClass().getSimpleName() + " - DML");
    msg("----------------------------------------------------------");
    msg("Transaction 1 will execute DML, transaction 2 will just change its data.");

    Thread t = new Thread()
    {
      @Override
      public void run()
      {
        try
        {
          IDBConnectionProvider provider = getConnectionProvider();
          Connection transaction2 = provider.getConnection();
          Statement tx2stmt = transaction2.createStatement();
          transaction2.setAutoCommit(false);
          tx2stmt.executeUpdate("update status_table set status = 'changed' where trans = 'transaction2'");
          tx2stmt.executeUpdate("update change_table set status = 'changed' where trans = 'transaction2'");
          tx2stmt.close();
          sleep(1000);
          transaction2.rollback();
          transaction2.close();
        }
        catch (Exception e)
        {
          throw new Error(e);
        }
      }
    };

    t.start();
    Thread.sleep(100);

    IDBConnectionProvider provider = getConnectionProvider();
    Connection transaction1 = provider.getConnection();
    transaction1.setAutoCommit(false);

    Statement tx1stmt = transaction1.createStatement();

    tx1stmt.executeUpdate("update status_table set status = 'changed' where trans = 'transaction1'");
    tx1stmt.executeUpdate("update change_table set status = 'changed' where trans = 'transaction1'");

    tx1stmt.execute("alter table change_table add new_column varchar(255) default 'added column present'");

    tx1stmt.close();

    transaction1.rollback();
    transaction1.close();

    t.join();

    Connection view = provider.getConnection();

    msg("transaction1: unchanged table record is "
        + select(view, "select status from status_table where trans = 'transaction1'").toUpperCase());
    msg("transaction2: unchanged table record is "
        + select(view, "select status from status_table where trans = 'transaction2'").toUpperCase());

    msg("transaction1: changed table record is "
        + select(view, "select status from change_table where trans = 'transaction1'").toUpperCase());
    msg("transaction2: changed table record is "
        + select(view, "select status from change_table where trans = 'transaction2'").toUpperCase());

    String present = "present";
    try
    {
      select(view, "select new_column from change_table where trans = 'transaction2'");
    }
    catch (SQLException e)
    {
      present = "not present";
    }

    msg("Added column is " + present.toUpperCase());
    view.close();

    msg("----------------------------------------------------------");
  }

  @Override
  protected void setUp() throws Exception
  {
    // create table
    Connection conn = getConnectionProvider().getConnection();
    conn.setAutoCommit(false);
    Statement stmt = conn.createStatement();

    // make sure tables don't exist!
    try
    {
      stmt.execute("drop table status_table");
    }
    catch (Exception e)
    {
    }

    try
    {
      stmt.execute("drop table change_table");
    }
    catch (Exception e)
    {
    }

    stmt.execute("create table status_table (trans varchar(255), status varchar(255))");
    stmt.execute("insert into status_table values ('transaction1', 'unchanged')");
    stmt.execute("insert into status_table values ('transaction2', 'unchanged')");

    stmt.execute("create table change_table (trans varchar(255), status varchar(255))");
    stmt.execute("insert into change_table values ('transaction1', 'unchanged')");
    stmt.execute("insert into change_table values ('transaction2', 'unchanged')");

    conn.commit();
    stmt.close();
    conn.close();
  }

  @Override
  protected void tearDown() throws Exception
  {
    Connection conn = getConnectionProvider().getConnection();
    conn.setAutoCommit(true);
    Statement stmt = conn.createStatement();

    stmt.execute("drop table status_table");
    stmt.execute("drop table change_table");

    stmt.close();
    conn.close();
  }

  protected abstract IDBConnectionProvider getConnectionProvider();

  private void msg(String string)
  {
    System.out.println(string);
  }

  private String select(Connection conn, String sql) throws SQLException
  {
    ResultSet rs = null;
    try
    {
      rs = conn.createStatement().executeQuery(sql);
      rs.next();
      return rs.getString(1);
    }
    finally
    {
      if (rs != null)
      {
        try
        {
          rs.close();
        }
        catch (SQLException ex)
        {
          // NOP
        }
      }
    }
  }

  @SuppressWarnings("unused")
  private void sqlDump(Connection conn, String sql)
  {
    ResultSet rs = null;
    try
    {
      System.out.format("Dumping output of %s\n", sql); //$NON-NLS-1$
      rs = conn.createStatement().executeQuery(sql);
      int numCol = rs.getMetaData().getColumnCount();

      StringBuilder row = new StringBuilder(" ");
      for (int c = 1; c <= numCol; c++)
      {
        row.append(String.format("%15s | ", rs.getMetaData().getColumnLabel(c))); //$NON-NLS-1$
      }

      System.out.println(row.toString());

      row = new StringBuilder();
      for (int c = 1; c <= numCol; c++)
      {
        row.append("-----------------+"); //$NON-NLS-1$
      }

      System.out.println(row.toString());

      while (rs.next())
      {
        row = new StringBuilder(" ");
        for (int c = 1; c <= numCol; c++)
        {
          row.append(String.format("%15s | ", rs.getString(c))); //$NON-NLS-1$
        }

        System.out.println(row.toString());
      }

      row = new StringBuilder();
      for (int c = 1; c <= numCol; c++)
      {
        row.append("-----------------+"); //$NON-NLS-1$
      }

      System.out.println(row.toString());
    }
    catch (SQLException ex)
    {
      // NOP
    }
    finally
    {
      if (rs != null)
      {
        try
        {
          rs.close();
        }
        catch (SQLException ex)
        {
          // NOP
        }
      }
    }
  }
}
