package edu.uiowa.icts.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Properties;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dbunit.DBTestCase;
import org.dbunit.PropertiesBasedJdbcDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.junit.After;
import org.junit.Before;

import edu.uiowa.icts.service.PropertyLoader;

public abstract class BaseIctsTestCase extends DBTestCase {

	protected final Log log = LogFactory.getLog( getClass().getName() );

	protected Properties properties;

	private String dataset = null;
	private boolean useAltData = false;
	private boolean buildSchema = false;
	private String schemaSqlFile = null;

	public BaseIctsTestCase() {
		log.debug( "setting database properties" );

		properties = PropertyLoader.loadProperties( "test.properties" );

		System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver" );
		System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:mem:testdb" );
		System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa" );
		System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "" );
	}

	@Before
	public void setUp() throws Exception {
		log.debug( "=== starting " + getName() + " =============================" );
		log.debug( getConnection().getConfig().getProperty( "http://www.dbunit.org/properties/datatypeFactory" ) );

		if ( isBuildSchema() ) {
			File f = new File( getSchemaSqlFile() );

			Class.forName( System.getProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS ) );

			Properties props = new Properties();
			props.setProperty( "user", System.getProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME ) );
			props.setProperty( "password", System.getProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD ) );

			Connection conn = DriverManager.getConnection( System.getProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL ), props );

			assertNotNull( conn );

			StringWriter output = new StringWriter();
			FileInputStream fis = new FileInputStream( f );
			try {
				IOUtils.copy( fis, output );
			} finally {
				fis.close();
			}

			Statement stmt = conn.createStatement();
			stmt.execute( "SET DATABASE SQL SYNTAX PGS TRUE" );
			stmt = conn.createStatement();
			stmt.executeUpdate( output.toString() );
			stmt.close();
		}

		super.setUp();
	}

	@After
	public void tearDown() throws Exception {
		log.debug( "=== ending " + getName() + " =============================\n" );
		super.tearDown();
	}

	@Override
	protected IDataSet getDataSet() throws Exception {
		String file_name = getDatasetName();
		if ( !isUseAltData() ) {
			file_name = properties.getProperty( "dataset.file.name", "dataset.xml" );
		}

		log.debug( "loading " + file_name + " as data set" );

		InputStream in = this.getClass().getClassLoader().getResourceAsStream( file_name );
		FlatXmlDataSetBuilder fxdsb = new FlatXmlDataSetBuilder();
		fxdsb.setCaseSensitiveTableNames( false );
		fxdsb.setColumnSensing( true );
		IDataSet datset = fxdsb.build( in );
		return datset;
	}

	protected void setUpDatabaseConfig( DatabaseConfig config ) {
		log.debug( "setting database config" );
		config.setProperty( "http://www.dbunit.org/properties/datatypeFactory", new MsSqlDataTypeFactory() );
		config.setProperty( DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true );
		config.setProperty( DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, false );

	}

	public void setDataset( String dataset ) {
		this.dataset = dataset;
		setUseAltData( true );
	}

	public String getDatasetName() {
		if ( dataset == null ) {
			setDataset( "dataset.xml" );
		}
		return dataset;
	}

	public void setUseAltData( boolean useAltData ) {
		this.useAltData = useAltData;
	}

	public boolean isUseAltData() {
		return useAltData;
	}

	public boolean isBuildSchema() {
		return buildSchema;
	}

	public void setBuildSchema( boolean buildSchema ) {
		this.buildSchema = buildSchema;
	}

	public String getSchemaSqlFile() {
		return schemaSqlFile;
	}

	public void setSchemaSqlFile( String schemaSqlFile ) {
		this.schemaSqlFile = schemaSqlFile;
	}

}

@@ -2959,16 +2959,19 @@
 ption %7B%0A
+%09%09%0A
 %09%09String
@@ -3253,16 +3253,19 @@
 name );%0A
+%09%09%0A
 %09%09FlatXm
@@ -3396,16 +3396,17 @@
 true );%0A
+%0A
 %09%09IDataS
@@ -3408,16 +3408,35 @@
 DataSet 
+datset;%0A%09%09try %7B%0A%09%09%09
 datset =
@@ -3455,16 +3455,50 @@
 ( in );%0A
+%09%09%7D finally %7B%0A%09%09%09in.close();%0A%09%09%7D%0A%0A
 %09%09return

test case update