/*
 *
 * Derby - Class org.apache.derbyTesting.functionTests.util.CleanDatabase
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific 
 * language governing permissions and limitations under the License.
 */
package org.apache.derbyTesting.junit;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

import junit.framework.Test;

/**
 * Test decorator that cleans a database on setUp and
 * tearDown to provide a test with a consistent empty
 * database as a starting point. The obejcts are cleaned
 * (dropped) on tearDown to ensure any filures dropping
 * the objects can easily be associated with the test
 * fixtures that created them.
 * <P>
 * Tests can extend to provide a decorator that defines
 * some schema items and then have CleanDatabaseTestSetup
 * automatically clean them up by implementing the decorateSQL method.. 
 * As an example:
 * <code>
        return new CleanDatabaseTestSetup(suite) {
            protected void decorateSQL(Statement s) throws SQLException {

                s.execute("CREATE TABLE T (I INT)");
                s.execute("CREATE INDEX TI ON T(I)")

            }
        };
 * </code>
 * 
 */
public class CleanDatabaseTestSetup extends BaseJDBCTestSetup {

    /**
     * Decorator this test with the cleaner
     */
    public CleanDatabaseTestSetup(Test test) {
        super(test);
    }
    /**
     * Constructor to use when running in a client / server 
     * with the server already started on a given host
     * and port.
     */
    /*
     * Currently only used in o.a.dT.ft.tests.replicationTests.StandardTests
     * for running existing JUnit tests on a client server configuration.
     * To avoid duplicating the code inside decorateSQL() methods
     * public static decorate() methods have been factored out
     * for reuse in test methods in StandardTests: e.g. as AnsiTrimTest.decorate(s);
     */
    public CleanDatabaseTestSetup(Test test, 
            boolean useNetworkClient,
            String hostName,
            int portNo) {
        super(test);
        if ( useNetworkClient )
        {
            this.jdbcClient = JDBCClient.DERBYNETCLIENT;
        }
        this.hostName = hostName;
        this.portNo = portNo;
    }
    private JDBCClient jdbcClient = null;
    private String hostName = null;
    private int portNo = -1;

    /**
     * Clean the default database using the default connection
     * and calls the decorateSQL to allow sub-classes to
     * initialize their schema requirments.
     */
    protected void setUp() throws Exception {
        if (jdbcClient != null )
        { // We have network client (useNetworkClient) on a given host and port.
            TestConfiguration current = TestConfiguration.getCurrent();
            TestConfiguration modified = new TestConfiguration(current, 
                    jdbcClient,
                    hostName, 
                    portNo);
            TestConfiguration.setCurrent(modified);
        }
        Connection conn = getConnection();
        conn.setAutoCommit(false);
        
        // compress as well to allow the fixtures wrapped in
        // this decorator to start with a clean database.
        CleanDatabaseTestSetup.cleanDatabase(conn, true);  
        
        Statement s = conn.createStatement();
        try {
            decorateSQL(s);
            s.close();
            conn.commit();
        } finally {
            // Make sure we release any locks held by the connection at this
            // point. Not doing so may cause subsequent tests to fail.
            try {
                clearConnection();
            } catch (SQLException sqle) {
                // Ignore, but print details in debug mode.
                if (getTestConfiguration().isVerbose()) {
                    println("clearing connection failed: " + sqle.getMessage());
                    sqle.printStackTrace(System.err);
                }
            }
        }
    }
    
    /**
     * Sub-classes can override this method to execute
     * SQL statements executed at setUp time once the
     * database has been cleaned.
     * Once this method returns the statement will be closed,
     * commit called and the connection closed. The connection
     * returned by s.getConnection() is the default connection
     * and is in auto-commit false mode.
     * <BR>
     * This implementation does nothing. Sub-classes need not call it.
     * @throws SQLException
     */
    protected void decorateSQL(Statement s) throws SQLException
    {
        // nothing in the default case.
    }

    /**
     * Clean the default database using the default connection.
     */
    protected void tearDown() throws Exception {
        Connection conn = getConnection();
        // See DERBY-5686 - perhaps there's a test that leaves a 
        // connection in read-only state - let's check here and 
        // if there's a conn that's read-only, unset it, and make
        // the test fail so we find it.
        conn.setAutoCommit(false);
        boolean ok=true;
        if (conn.isReadOnly())
        {
            conn.setReadOnly(false);
            ok=false;
        }
        
        // Clean the database, ensures that any failure dropping
        // objects can easily be linked to test fixtures that
        // created them
        //
        // No need to compress, any test requiring such a clean
        // setup should not assume it is following another test
        // with this decorator, it should wrap itself in a CleanDatabaseTestSetup.
        // Compress is a somewhat expensive operation so avoid it if possible.
        CleanDatabaseTestSetup.cleanDatabase(conn, false);       
        super.tearDown();
        if (!ok)
            fail("the test that was just run left the conn read-only");
    }

    /**
     * Clean a complete database
     * @param conn Connection to be used, must not be in auto-commit mode.
     * @param compress True if selected system tables are to be compressed
     * to avoid potential ordering differences in test output.
     * @throws SQLException database error
     */
     public static void cleanDatabase(Connection conn, boolean compress) throws SQLException {
         clearProperties(conn);
         removeObjects(conn);
         if (compress)
             compressObjects(conn);
         removeRoles(conn);
         removeUsers( conn );
     }
     
     /**
      * Set of database properties that will be set to NULL (unset)
      * as part of cleaning a database.
      */
     private static final String[] CLEAR_DB_PROPERTIES =
     {
         "derby.database.classpath",
     };
     
     /**
      * Clear all database properties.
      */
     private static void clearProperties(Connection conn) throws SQLException {

         PreparedStatement ps = conn.prepareCall(
           "CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(?, NULL)");
         
         for (int i = 0; i < CLEAR_DB_PROPERTIES.length; i++)
         {
             ps.setString(1, CLEAR_DB_PROPERTIES[i]);
             ps.executeUpdate();
         }
         ps.close();
         conn.commit();
     }
     
     
     /**
      * Remove all objects in all schemas from the database.
      */
     private static void removeObjects(Connection conn) throws SQLException {
   
        DatabaseMetaData dmd = conn.getMetaData();

        SQLException sqle = null;
        // Loop a number of arbitary times to catch cases
        // where objects are dependent on objects in
        // different schemas.
        for (int count = 0; count < 5; count++) {
            // Fetch all the user schemas into a list
            List<String> schemas = new ArrayList<String>();
            ResultSet rs = dmd.getSchemas();
            while (rs.next()) {
    
                String schema = rs.getString("TABLE_SCHEM");
                if (schema.startsWith("SYS"))
                    continue;
                if (schema.equals("SQLJ"))
                    continue;
                if (schema.equals("NULLID"))
                    continue;
    
                schemas.add(schema);
            }
            rs.close();
    
            // DROP all the user schemas.
            sqle = null;
            for (String schema : schemas) {
                try {
                    JDBC.dropSchema(dmd, schema);
                } catch (SQLException e) {
                    sqle = e;
                }
            }
            // No errors means all the schemas we wanted to
            // drop were dropped, so nothing more to do.
            if (sqle == null)
                return;
        }
        throw sqle;
    }

    private static void removeRoles(Connection conn) throws SQLException {
        // No metadata for roles, so do a query against SYSROLES
        Statement stm = conn.createStatement();
        Statement dropStm = conn.createStatement();

        // cast to overcome territory differences in some cases:
        ResultSet rs = stm.executeQuery(
            "select roleid from sys.sysroles where " +
            "cast(isdef as char(1)) = 'Y'");

        while (rs.next()) {
            dropStm.executeUpdate("DROP ROLE " + JDBC.escape(rs.getString(1)));
        }

        stm.close();
        dropStm.close();
        conn.commit();
    }

    /** Drop all credentials stored in SYSUSERS */
    private static void removeUsers(Connection conn) throws SQLException
    {
        // Get the users
        Statement stm = conn.createStatement();
        ResultSet rs = stm.executeQuery( "select username from sys.sysusers" );
        ArrayList<String> users = new ArrayList<String>();
        
        while ( rs.next() ) { users.add( rs.getString( 1 ) ); }
        rs.close();
        stm.close();

        // Now delete them
        PreparedStatement   ps = conn.prepareStatement( "call syscs_util.syscs_drop_user( ? )" );

        for ( int i = 0; i < users.size(); i++ )
        {
            ps.setString( 1, (String) users.get( i ) );

            // you can't drop the DBO's credentials. sorry.
            try {
                ps.executeUpdate();
            }
            catch (SQLException se)
            {
                if ( "4251F".equals( se.getSQLState() ) ) { continue; }
                else { throw se; }
            }
        }

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

     /**
      * Set of objects that will be compressed as part of cleaning a database.
      */
     private static final String[] COMPRESS_DB_OBJECTS =
     {
         "SYS.SYSDEPENDS",
     };
     
     /**
      * Compress the objects in the database.
      * 
      * @param conn the db connection
      * @throws SQLException database error
      */
     private static void compressObjects(Connection conn) throws SQLException {
    	 
    	 CallableStatement cs = conn.prepareCall
    	     ("CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE(?, ?, 1, 1, 1)");
    	 
    	 for (int i = 0; i < COMPRESS_DB_OBJECTS.length; i++)
    	 {
    		 int delim = COMPRESS_DB_OBJECTS[i].indexOf(".");
             cs.setString(1, COMPRESS_DB_OBJECTS[i].substring(0, delim) );
             cs.setString(2, COMPRESS_DB_OBJECTS[i].substring(delim+1) );
             cs.execute();
    	 }
    	 
    	 cs.close();
    	 conn.commit();
     }
    	   
}
