/**************************************************************
 * 
 * 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 mod._dbaccess;

import java.io.PrintWriter;
import java.util.Vector;

import lib.Status;
import lib.StatusException;
import lib.TestCase;
import lib.TestEnvironment;
import lib.TestParameters;
import util.DBTools;
import util.utils;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.sdb.CommandType;
import com.sun.star.sdb.ParametersRequest;
import com.sun.star.sdb.XInteractionSupplyParameters;
import com.sun.star.sdbc.XConnection;
import com.sun.star.sdbc.XResultSet;
import com.sun.star.sdbc.XResultSetUpdate;
import com.sun.star.sdbc.XRow;
import com.sun.star.sdbc.XRowSet;
import com.sun.star.sdbc.XRowUpdate;
import com.sun.star.task.XInteractionAbort;
import com.sun.star.task.XInteractionContinuation;
import com.sun.star.task.XInteractionRequest;
import com.sun.star.ucb.AuthenticationRequest;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import com.sun.star.util.XCloseable;
import com.sun.star.frame.XModel;
import com.sun.star.sdb.RowChangeEvent;
import com.sun.star.sdbc.SQLException;
import com.sun.star.sdbc.XParameters;
import ifc.sdb._XCompletedExecution;
import util.db.DataSource;
import util.db.DataSourceDescriptor;

/**
 * Test for object which is represented by service
 * <code>com.sun.star.sdb.RowSet</code>. <p>
 *
 * The following files used by this test :
 * <ul>
 *  <li><b> TestDB/TestDB.dbf </b> : the database file with some
 *    predefined fields described in <code>util.DBTools</code>.
 *    The copy of this file is always made in temp directory for
 *    testing purposes.</li>
 * </ul>
 * The following parameters in ini-file used by this test:
 * <ul>
 *   <li><code>test.db.url</code> - URL to MySQL database.
 *   For example: <code>mysql://mercury:3306/api_current</code></li>
 *   <li><code>test.db.user</code> - user for MySQL database</li>
 *   <li><code>test.db.password</code> - password for MySQL database</li>
 * </ul>
 *
 * @see com.sun.star.sdbc.RowSet
 * @see com.sun.star.sdbcx.XRowLocate
 * @see com.sun.star.sdbc.XResultSetUpdate
 * @see com.sun.star.util.XCancellable
 * @see com.sun.star.sdbc.XParameters
 * @see com.sun.star.sdbc.XResultSetMetaDataSupplier
 * @see com.sun.star.sdbcx.XDeleteRows
 * @see com.sun.star.sdbc.XCloseable
 * @see com.sun.star.sdbcx.XColumnsSupplier
 * @see com.sun.star.sdb.XResultSetAccess
 * @see com.sun.star.sdbc.XResultSet
 * @see com.sun.star.sdbc.XColumnLocate
 * @see com.sun.star.sdbc.XRowSet
 * @see com.sun.star.sdb.RowSet
 * @see com.sun.star.sdbc.XRowUpdate
 * @see com.sun.star.sdb.XRowSetApproveBroadcaster
 * @see com.sun.star.beans.XPropertySet
 * @see com.sun.star.sdbc.XRow
 * @see com.sun.star.sdbc.XWarningsSupplier
 * @see com.sun.star.lang.XComponent
 * @see com.sun.star.sdbcx.ResultSet
 * @see com.sun.star.sdbc.ResultSet
 * @see ifc.sdbc._RowSet
 * @see ifc.sdbcx._XRowLocate
 * @see ifc.sdbc._XResultSetUpdate
 * @see ifc.util._XCancellable
 * @see ifc.sdbc._XParameters
 * @see ifc.sdbc._XResultSetMetaDataSupplier
 * @see ifc.sdbcx._XDeleteRows
 * @see ifc.sdbc._XCloseable
 * @see ifc.sdbcx._XColumnsSupplier
 * @see ifc.sdb._XResultSetAccess
 * @see ifc.sdbc._XResultSet
 * @see ifc.sdbc._XColumnLocate
 * @see ifc.sdbc._XRowSet
 * @see ifc.sdb._RowSet
 * @see ifc.sdbc._XRowUpdate
 * @see ifc.sdb._XRowSetApproveBroadcaster
 * @see ifc.beans._XPropertySet
 * @see ifc.sdbc._XRow
 * @see ifc.sdbc._XWarningsSupplier
 * @see ifc.lang._XComponent
 * @see ifc.sdbcx._ResultSet
 * @see ifc.sdbc._ResultSet
 */
public class ORowSet extends TestCase {

    private static int uniqueSuffix = 0 ;
    private DBTools dbTools     = null ;
    private static String origDB = null ;
    String tableName = null;
    DataSourceDescriptor srcInf = null;
    boolean isMySQLDB = false;
    protected final static String dbSourceName = "ORowSetDataSource";
    public XConnection m_connection = null;
    private Object m_rowSet = null;
    private DataSource m_dataSource;
    private String m_tableFile;
    private XMultiServiceFactory m_orb = null;

    /**
    * Initializes some class fields. Then creates DataSource, which serves
    * as a single source for all tables created in the test.
    * This DataSource then registered in the global
    * <code>DatabaseContext</code> service. This data source's URL
    * points to SOffice temp directory where tables are copied from
    * <code>TestDocuments</code> directory on every environment
    * creation.
    * To create DataSource for MySQL database next parameters required
    * in ini-file:
    * <ul>
    *   <li><code>test.db.url</code> - URL to MySQL database.
    *   For example: <code>mysql://mercury:3306/api_current</code></li>
    *   <li><code>test.db.user</code> - user for MySQL database</li>
    *   <li><code>test.db.password</code> - password for MySQL database</li>
    * </ul>
    *
    * @throws StatusException if DataSource can not be created or
    * registered.
    */
    protected void initialize ( TestParameters Param, PrintWriter _log)
        throws StatusException
    {
        m_orb = (XMultiServiceFactory)Param.getMSF();

        String tmpDir = utils.getOfficeTemp( m_orb );

        origDB = util.utils.getFullTestDocName("TestDB/testDB.dbf");

        dbTools = new DBTools( m_orb, _log );

        // creating DataSource and registering it in DatabaseContext
        String dbURL = (String) Param.get("test.db.url");
        String dbUser = (String) Param.get("test.db.user");
        String dbPassword = (String) Param.get("test.db.password");

        log.println("Creating and registering DataSource ...");
        srcInf = new DataSourceDescriptor( m_orb );
        if (dbURL != null && dbUser != null && dbPassword != null)
        {
            isMySQLDB = true;
            log.println("dbURL = " + dbURL);
            log.println("dbUSER = " + dbUser);
            log.println("dbPASSWORD = " + dbPassword);
            //DataSource for mysql db
            tableName = "soffice_test_table";
            srcInf.URL = "jdbc:" + dbURL;
            srcInf.IsPasswordRequired = new Boolean(true);
            srcInf.Password = dbPassword;
            srcInf.User = dbUser;
            PropertyValue[] propInfo = new PropertyValue[1];
            propInfo[0] = new PropertyValue();
            propInfo[0].Name = "JavaDriverClass";
            propInfo[0].Value = "org.gjt.mm.mysql.Driver";
            srcInf.Info = propInfo;
        }
        else
        {
            srcInf.URL = "sdbc:dbase:" + DBTools.dirToUrl(tmpDir);
        }
        m_dataSource = srcInf.createDataSource();
        m_dataSource.registerAs( dbSourceName, true );
    }

    /**
    * Creating a Testenvironment for the interfaces to be tested.
    * The database (DBF) file is copied from test document directory
    * into SOffice temp dir with unique name for each enviroment
    * creation. If the file cann't be copied (is not released)
    * then another unique name is used (file name suffix incremented
    * by 1).<p>
    *
    * <code>com.sun.star.sdb.RowSet</code> service created and its
    * source is all rows from the current copy of the table. Then
    * row set command ("select all rows from a table") is executed
    * and cursor is positioned to the first row. <p>
    *
    *     Object relations created :
    * <ul>
    *  <li> <code>'ORowSet.Connection'</code> for
    *      internal component test usage. Is used for
    *      closing connection when cleaning up environment. </li>
    *  <li> <code>'XRowSetApproveBroadcaster.ApproveChecker'</code> for
    *      {@link ifc.sdb._XRowSetApproveBroadcaster} interface
    *      implementation which made actions required </li>
    *  <li> <code>'CurrentRowData'</code> for
    *      {@link ifc.sdbc._XRow}, {@link ifc.sdbc._XRowUpdate} :
    *      exports types and values of the current row data.</li>
    *  <li> <code>'XColumnLocate.ColumnName'</code> for
    *      {@link ifc.sdbc._XColumnLocate} :
    *      the name of the first column of the table.</li>
    *  <li> <code>'XParameters.ParamValues'</code> for
    *      {@link ifc.sdbc._XParameters} :
    *      Collection of parameter types presented in the query. </li>
    *  <li> <code>'XRowUpdate.XRow'</code> for
    *      {@link ifc.sdbc._XRowUpdate} :
    *      <code>XRow</code> interface of the current component.</li>
    *  <li> <code>'XResultSetUpdate.UpdateTester'</code> for
    *      {@link ifc.sdbc._XResultSetUpdate} </li>
    * </ul>
    *
    * @see com.sun.star.sdb.DatabaseContext
    * @see com.sun.star.sdb.DataSource
    */
    protected TestEnvironment createTestEnvironment(TestParameters Param,
            PrintWriter log)
    {
        XMultiServiceFactory orb = (XMultiServiceFactory)Param.getMSF();
        uniqueSuffix++;
        boolean envCreatedOK = false ;
        
        //initialize test table
        if (isMySQLDB)
        {
            try
            {
                DBTools.DataSourceInfo legacyDescriptor = dbTools.newDataSourceInfo();
                legacyDescriptor.Name = srcInf.Name;
                legacyDescriptor.User = srcInf.User;
                legacyDescriptor.Password = srcInf.Password;
                legacyDescriptor.Info = srcInf.Info;
                legacyDescriptor.URL = srcInf.URL;
                legacyDescriptor.IsPasswordRequired = srcInf.IsPasswordRequired;
                dbTools.initTestTableUsingJDBC(tableName, legacyDescriptor);
            }
            catch(java.sql.SQLException e)
            {
                e.printStackTrace(log);
                throw new StatusException(Status.failed("Couldn't " +
                    " init test table. SQLException..."));
            }
            catch(java.lang.ClassNotFoundException e)
            {
                throw new StatusException(Status.failed("Couldn't " +
                    "register mysql driver"));
            }
        }
        else
        {
            String oldF = null ;
            String newF = null ;
            String tempFolder = utils.getOfficeTemp( orb );
            do
            {
                tableName = "ORowSet_tmp" + uniqueSuffix ;
                oldF = utils.getFullURL(origDB);
                newF = tempFolder + tableName + ".dbf";
            }
            while ( !utils.tryOverwriteFile( orb, oldF, newF ) );
            m_tableFile = newF;
        }
        
        try
        {
            m_rowSet = orb.createInstance("com.sun.star.sdb.RowSet");

            XPropertySet rowSetProps = UnoRuntime.queryInterface( XPropertySet.class, m_rowSet );

            log.println("Trying to open: " + tableName);

            rowSetProps.setPropertyValue("DataSourceName", dbSourceName);
            rowSetProps.setPropertyValue("Command", tableName);
            rowSetProps.setPropertyValue("CommandType",
                new Integer(CommandType.TABLE));

            final XRowSet rowSet = UnoRuntime.queryInterface( XRowSet.class, m_rowSet);                   
            rowSet.execute();
            m_connection = UnoRuntime.queryInterface( XConnection.class, rowSetProps.getPropertyValue("ActiveConnection") );

            XResultSet xRes = UnoRuntime.queryInterface( XResultSet.class, m_rowSet );
            xRes.first();

            log.println( "creating a new environment for object" );
            TestEnvironment tEnv = new TestEnvironment( (XInterface)m_rowSet );

            // Adding obj relation for XRowSetApproveBroadcaster test
            {
                final XResultSet resultSet = UnoRuntime.queryInterface( XResultSet.class, m_rowSet );
                final XResultSetUpdate resultSetUpdate = UnoRuntime.queryInterface( XResultSetUpdate.class, m_rowSet );
                final XRowUpdate rowUpdate = UnoRuntime.queryInterface(XRowUpdate.class, m_rowSet );
                final PrintWriter logF = log ;
                tEnv.addObjRelation( "XRowSetApproveBroadcaster.ApproveChecker",
                    new ifc.sdb._XRowSetApproveBroadcaster.RowSetApproveChecker()
                    {
                        public void moveCursor()
                        {
                            try
                            {
                                resultSet.beforeFirst();
                                resultSet.afterLast();
                                resultSet.first();
                            }
                            catch (com.sun.star.sdbc.SQLException e)
                            {
                                logF.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.moveCursor() :");
                                e.printStackTrace(logF);
                                throw new StatusException( "RowSetApproveChecker.moveCursor failed", e );
                            }
                        }
                        public RowChangeEvent changeRow()
                        {
                            try
                            {
                                resultSet.first();
                                rowUpdate.updateString(1, "ORowSetTest2");
                                resultSetUpdate.updateRow();
                            }
                            catch (com.sun.star.sdbc.SQLException e)
                            {
                                logF.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRow() :");
                                e.printStackTrace(logF);
                                throw new StatusException( "RowSetApproveChecker.changeRow failed", e );
                            }
                            RowChangeEvent ev = new RowChangeEvent();
                            ev.Action = com.sun.star.sdb.RowChangeAction.UPDATE ;
                            ev.Rows = 1 ;

                            return ev ;
                        }
                        public void changeRowSet()
                        {
                            try
                            {
                                // since we gave the row set a parametrized statement, we need to ensure the
                                // parameter is actually filled, otherwise we would get an empty result set,
                                // which would imply some further tests failing
                                XParameters rowSetParams = UnoRuntime.queryInterface( XParameters.class, resultSet );
                                rowSetParams.setString( 1, "String2" );
                                rowSet.execute();
                                resultSet.first();
                            }
                            catch (com.sun.star.sdbc.SQLException e)
                            {
                                logF.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRowSet() :");
                                e.printStackTrace(logF);
                                throw new StatusException( "RowSetApproveChecker.changeRowSet failed", e );
                            }
                        }
                    }
                );
            }
            // Adding relations for XRow as a Vector with all data
            // of current row of RowSet.

            Vector rowData = new Vector();

            for (int i = 0; i < DBTools.TST_TABLE_VALUES[0].length; i++) {
                rowData.add(DBTools.TST_TABLE_VALUES[0][i]);
            }

            // here XRef must be added
            // here XBlob must be added
            // here XClob must be added
            // here XArray must be added

            tEnv.addObjRelation("CurrentRowData", rowData);

            // Adding relation for XColumnLocate ifc test
            tEnv.addObjRelation( "XColumnLocate.ColumnName", DBTools.TST_STRING_F );

            // Adding relation for XCompletedExecution
            tEnv.addObjRelation( "InteractionHandlerChecker", new InteractionHandlerImpl() );
            try
            {
                String sqlCommand = isMySQLDB
                    ?   "SELECT Column0  FROM soffice_test_table  WHERE ( (  Column0 = :param1 ) )"
                    :   "SELECT \"_TEXT\" FROM \"" + tableName + "\" WHERE ( ( \"_TEXT\" = :param1 ) )";
                rowSetProps.setPropertyValue( "DataSourceName", dbSourceName );
                rowSetProps.setPropertyValue( "Command", sqlCommand );
                rowSetProps.setPropertyValue( "CommandType", new Integer(CommandType.COMMAND) );
            }
            catch(Exception e)
            {
                throw new StatusException( "setting up the RowSet with a parametrized command failed", e );
            }

            // Adding relation for XParameters ifc test
            tEnv.addObjRelation( "XParameters.ParamValues", new Vector() );

            // Adding relation for XRowUpdate
            final XRow row = UnoRuntime.queryInterface( XRow.class, m_rowSet );
            tEnv.addObjRelation("XRowUpdate.XRow", row);

            // Adding relation for XResultSetUpdate
            {
                final XResultSet resultSet = UnoRuntime.queryInterface( XResultSet.class, m_rowSet );
                final XRowUpdate rowUpdate = UnoRuntime.queryInterface( XRowUpdate.class, m_rowSet );

                tEnv.addObjRelation("XResultSetUpdate.UpdateTester",
                    new ifc.sdbc._XResultSetUpdate.UpdateTester()
                    {
                        String lastUpdate = null ;

                        public int rowCount() throws SQLException
                        {
                            int prevPos = resultSet.getRow();
                            resultSet.last();
                            int count = resultSet.getRow();
                            resultSet.absolute(prevPos);

                            return count ;
                        }

                        public void update() throws SQLException
                        {
                            lastUpdate = row.getString(1);
                            lastUpdate += "_" ;
                            rowUpdate.updateString(1, lastUpdate);
                        }

                        public boolean wasUpdated() throws SQLException
                        {
                            String getStr = row.getString(1);
                            return lastUpdate.equals(getStr);
                        }

                        public int currentRow() throws SQLException
                        {
                            return resultSet.getRow();
                        }
                    }
                );
            }

            envCreatedOK = true ;
            return tEnv;

        }
        catch(com.sun.star.uno.Exception e)
        {
            log.println( "couldn't set up tes tenvironment:" );
            e.printStackTrace(log);
            try
            {
                if ( m_connection != null )
                    m_connection.close();
            }
            catch(Exception ex)
            {
            }
            throw new StatusException( "couldn't set up tes tenvironment", e );
        }
        finally
        {
            if (!envCreatedOK)
            {
                try
                {
                    m_connection.close();
                }
                catch(Exception ex)
                {
                }
            }
        }

    } // finish method getTestEnvironment

    /**
    * Closes connection of <code>RowSet</code> instance created.
    */
    protected void cleanup( TestParameters Param, PrintWriter log)
    {
        String doing = null;
        try
        {
            doing = "revoking data source registration";
            log.println( doing );
            m_dataSource.revokeRegistration();

            doing = "closing database document";
            log.println( doing );
            XModel databaseDocModel = UnoRuntime.queryInterface( XModel.class,
                m_dataSource.getDatabaseDocument().getDatabaseDocument() );
            String documentFile = databaseDocModel.getURL();

            XCloseable closeModel = UnoRuntime.queryInterface( XCloseable.class,
                m_dataSource.getDatabaseDocument().getDatabaseDocument() );
            closeModel.close( true );

            if ( m_rowSet != null )
            {
                doing = "disposing row set";
                log.println( doing );
                XComponent rowSetComponent = UnoRuntime.queryInterface( XComponent.class, m_rowSet );
                rowSetComponent.dispose();
            }

            try
            {
                doing = "closing connection";
                log.println( doing );
                m_connection.close();
            }
            catch (com.sun.star.lang.DisposedException e)
            {
                log.println( "already closed - okay." );
            }

            doing = "deleting database file ("  + documentFile + ")";
            log.println( doing );
            impl_deleteFile( documentFile );

            if ( m_tableFile != null )
            {
                doing = "deleting dBase table file (" + m_tableFile + ")";
                log.println( doing );
                impl_deleteFile( m_tableFile );
            }
        }
        catch (com.sun.star.uno.Exception e)
        {
            log.println( "error: ");
            e.printStackTrace(log);
        }
    }

    private final void impl_deleteFile( final String _file )
    {
        java.io.File file = new java.io.File( _file );
        file.delete();
        if ( file.exists() )
            file.deleteOnExit();
    }

    /**
     * Implementation of interface _XCompletedExecution.CheckInteractionHandler
     * for the XCompletedExecution test
     * @see ifc.sdb._XCompletedExecution
     */
    public class InteractionHandlerImpl implements _XCompletedExecution.CheckInteractionHandler {
        private boolean handlerWasUsed = false;
        private PrintWriter log = new PrintWriter(System.out);
        
        public boolean checkInteractionHandler() {
            return handlerWasUsed;
        }
        
        public void handle(XInteractionRequest xInteractionRequest) {
            log.println("### _XCompletedExecution.InteractionHandlerImpl: handle called.");
            ParametersRequest req = null;
            boolean abort = false;
            
            Object o = xInteractionRequest.getRequest();
            if (o instanceof ParametersRequest) {
                req = (ParametersRequest)o;
            }
            else if (o instanceof AuthenticationRequest) {
                log.println("### The request in XCompletedExecution is of type 'AuthenticationRequest'");
                log.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
                abort = true;
            }
            else {
                log.println("### Unknown request:" + o.toString());
                log.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
                abort = true;
            }
                
            XInteractionContinuation[]xCont = xInteractionRequest.getContinuations();
            XInteractionSupplyParameters xParamCallback = null;
            for(int i=0; i<xCont.length; i++) {
                if (abort) {
                    XInteractionAbort xAbort = null;
                    xAbort = UnoRuntime.queryInterface(XInteractionAbort.class, xCont[i]);
                    if (xAbort != null)
                        xAbort.select();
                        return;
                }
                else {
                    xParamCallback = UnoRuntime.queryInterface(XInteractionSupplyParameters.class, xCont[i]);
                    if (xParamCallback != null)
                        break;
                }
            }
            if (xParamCallback != null) {
                log.println("### _XCompletedExecution.InteractionHandlerImpl: supplying parameters.");
                handlerWasUsed = true;
                PropertyValue[] prop = new PropertyValue[1];
                prop[0] = new PropertyValue();
                prop[0].Name = "param1";
                prop[0].Value = "Hi.";

                xParamCallback.setParameters(prop);
                xParamCallback.select();
            }
            else { // we should never reach this: abort has to be true first.
                log.println("### _XCompletedExecution.InteractionHandlerImpl: Got no " + 
                            "'XInteractionSupplyParameters' and no 'XInteractionAbort'.");
            }
        }
        
        public void setLog(PrintWriter log) {
            this.log = log;
        }
        
    }
}
