/**************************************************************
 * 
 * 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 basicrunner;


import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.connection.ConnectionSetupException;
import com.sun.star.container.ContainerEvent;
import com.sun.star.container.XContainer;
import com.sun.star.container.XContainerListener;
import com.sun.star.container.XNameContainer;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.util.XChangesBatch;
import java.util.Hashtable;
import lib.TestParameters;

import share.LogWriter;


/**
 * This class is a java-part of BASIC-java interaction "driver"
 * It is used to call Star-Basic's function from java using
 * basic's part of "driver" where listeners are implemented.
 * The instance of the BasicHandler should be added to the MSF that will be 
 * used for loading BASIC's part of "driver".<br>
 * After opening basic's document it creates an instance of the 
 * HandlerContainer using BasicHandler. HandlerContainer is a UNO
 * XContainer and XNameContainer.
 * Only one instance of BasicHandler can be used at the moment.
 * @see com.sun.star.lang.XServiceInfo
 * @see com.sun.star.lang.XSingleServiceFactory
 */
public class BasicHandler implements XServiceInfo, XSingleServiceFactory {
    /**
     * serviceName is the name of service that can be created in BASIC.
     */
    static final String serviceName = 
                            "com.sun.star.jsuite.basicrunner.BasicHandler";

    /**
     * <code>container</code> is a SHARED variable (between BASIC and Java). 
     * It is used for interacting.
     */
    static private HandlerContainer container = null;

    /**
     * Contains a writer to log an information about the interface testing, to
     * allows for tests to access it.
     */
    static private LogWriter log;

    /**
     * <code>oHandlerDoc</code> is a referrence to BASIC's document.
     */
    static private XComponent oHandlerDoc = null;

    /**
     * <code>xMSF</code> is a MultiServiceFactory currently used by
     * BasicHandler.
     */
    static private XMultiServiceFactory xMSF = null;

    /**
     * Interface being tested now.
     */
    static private BasicIfcTest TestedInterface = null;

    /**
     * Ab enhanced scheme of timeouts can be used with BASIC tests.
     * A small timeout can be used zo wait for changes in the test status.
     * <code>respFlag</code> is set to <code>true</code> when a BASIC test
     * writes any log information.
     */
    static private boolean respFlag = false;

    /**
     * <code>iBasicTimeout</code> is the amount of milliseconds that 
     * the BasicHandler will wait for a response from tests 
     * (finish to execute a method or add log information) 
     * before it decides that SOffice is dead.
     */
    static private int iBasicTimeout = 10000;



    /**
     * Creates an instance of a HandlerContainer. This instance is used from
     * BASIC.
     * @param tParam The test parameters.
     */
    public BasicHandler(TestParameters tParam) {
        if (tParam.get("soapi.test.basic.debugFile") != null) {
            iBasicTimeout = 0; // Debug mode.
        }
        container = new HandlerContainer(this);
    }

    /**
     * Set the tested interface and a log writer.
     * @param ifc The test of an interface
     * @param log A log writer. 
     */
    public void setTestedInterface(BasicIfcTest ifc, LogWriter log) {
        this.log = log;
        TestedInterface = ifc;
    }

    /**
     * Is called when BASIC signals that it has performed the test of a method.
     * @param methodName The name of the method.
     * @bResult The result of the test.
     */
    synchronized void methodTested(String methodName, boolean bResult) {
        respFlag = true;
        TestedInterface.methodTested(methodName, bResult);
        notify() ;
    }

    /**
     * Is called when BASIC sends a signal to write some log information.
     * @param info The string to write.
     */
    synchronized public void Log(String info) {
        respFlag = true;
        log.println(info);
        notify() ;
    }

    /**
     * Is called by BasicIfcTest to find out if this BasicHandler uses the
     * correct MultiServiceFactory.
     * @param xMSF The MultiServiceFactory
     * @see com.sun.star.lang.XMultiServiceFactory
     * @return True, if xMSF is equal to the MultiServiceFactory of this class.
     */
    public boolean isUptodate(XMultiServiceFactory xMSF) {
        return xMSF.equals(this.xMSF);
    }


    /**
     * Establishes a connection between BASIC and Java.
     * If required, hte BASIC part of the "driver" is loaded.
     * @param sBasicBridgeURL The URL of the basic bridge document
     *                                           (BasicBridge.sxw)
     * @param tParam The test parameters.
     * @param xMSF The MultiServiceFactory
     * @param log The log writer.
     * @see com.sun.star.lang.XMultiServiceFactory
     * @throws ConnectionSetupException Exception is thrown, if no connection could be made.
     */
    public synchronized void Connect(String sBasicBridgeURL, 
                            TestParameters tParam, XMultiServiceFactory xMSF, 
                            LogWriter log) throws ConnectionSetupException {
        this.log = log;
        try {
            this.xMSF = xMSF;
            Object oInterface = xMSF.createInstance(
                                                "com.sun.star.frame.Desktop");
            XDesktop oDesktop = (XDesktop) UnoRuntime.queryInterface(
                                                XDesktop.class, oInterface);
            XComponentLoader oCLoader = (XComponentLoader)
                                        UnoRuntime.queryInterface(
                                        XComponentLoader.class, oDesktop);
            
            // load BasicBridge with MarcoEceutionMode = Always-no warn
            //PropertyValue[] DocArgs = null;
            PropertyValue[] DocArgs = new PropertyValue[1];
            PropertyValue DocArg = new PropertyValue();
            DocArg.Name = "MacroExecutionMode";
            DocArg.Value = new Short(
                    com.sun.star.document.MacroExecMode.ALWAYS_EXECUTE_NO_WARN);
            DocArgs[0] = DocArg; 

            // configure Office to allow to execute macos
            PropertyValue [] ProvArgs = new PropertyValue [1];
            PropertyValue Arg = new PropertyValue();
            Arg.Name = "nodepath";
            Arg.Value = "/org.openoffice.Office.Common/Security";
            ProvArgs[0] = Arg;
            
            Object oProvider = xMSF.createInstance(
                        "com.sun.star.configuration.ConfigurationProvider");
            
            XMultiServiceFactory oProviderMSF = (XMultiServiceFactory) 
                                    UnoRuntime.queryInterface(
                                    XMultiServiceFactory.class, oProvider);
            
            Object oSecure = oProviderMSF.createInstanceWithArguments(
                        "com.sun.star.configuration.ConfigurationUpdateAccess",
                        ProvArgs);  
            
            XPropertySet oSecureProps = (XPropertySet) 
                        UnoRuntime.queryInterface(XPropertySet.class, oSecure);
            
            Object oScripting = oSecureProps.getPropertyValue("Scripting");
            XPropertySet oScriptingSettings = (XPropertySet)
                    UnoRuntime.queryInterface(XPropertySet.class, oScripting);
            
            oScriptingSettings.setPropertyValue("Warning", Boolean.FALSE);
            oScriptingSettings.setPropertyValue("OfficeBasic", new Integer(2));
            
            XChangesBatch oSecureChange = (XChangesBatch) 
                    UnoRuntime.queryInterface(XChangesBatch.class, oSecure);
            oSecureChange.commitChanges();
            
            // As we want to have some information about a debugFile 
            // BEFORE connection is established
            // we pass the information about it in frame name.
            String sFrameName = (String)tParam.get(
                                                "soapi.test.basic.debugFile");
            if (sFrameName == null) sFrameName = "BasicRunner";

            oHandlerDoc = oCLoader.loadComponentFromURL(sBasicBridgeURL, 
                                                    sFrameName, 40, DocArgs);

            do {
                respFlag = false ;
                wait(10000); // waiting for basic response for 10 seconds.
            } while (respFlag && !container.hasByName("BASIC_Done")) ;

            if (!container.hasByName("BASIC_Done")) {
                throw new ConnectionSetupException("Connection timed out.");
            }
        } catch (Exception e) {
            System.out.println("Exception: " + e.toString());
            throw new ConnectionSetupException();
        }

        log.println("Java-BASIC connection established!");
    }

    /**
     * Overloads perform(Strin fName, Object params) for convenience.
     * @return A proprty value as result.
     *
    public synchronized PropertyValue perform(String fName) 
                                                        throws BasicException {
        return perform(fName, "");
    }
*/
    /**
     * Perform a test of a method.
     * @param fName The name of the method to test.
     * @param params The test parameters.
     * @return A proprty value as result of the test.
     * @throws BasicException The method could not be executed.
     */
    public synchronized PropertyValue perform(String fName, Object params) 
                                                        throws BasicException {
        try {
            container.callBasicFunction(fName, params);

            do {
                respFlag = false;
                // waiting for basic response for iBasicTimeout milliseconds.
                wait(iBasicTimeout); 
            } while(respFlag && !container.hasByName("BASIC_Done"));

        } catch (InterruptedException e) {
            System.out.println("The operation " + fName + " was interrupted.");
        } catch (com.sun.star.lang.DisposedException de) {
            System.out.println("## Office is disposed");
        }

        if (!container.hasByName("BASIC_Done")) {
            System.out.println("Operation timed out.");
                throw new BasicException(
                            "Operation timed out.");                  
        }

        Object res = container.getByName("BASIC_Done") ;
        container.removeByName("BASIC_Done");

        if (!(res instanceof PropertyValue)) {
            if (res == null) {
                System.out.println(
                            "BasicBridge returns null");
                throw new BasicException(
                            "BasicBridge returns null");                
            } else {
                System.out.println(
                            "BasicBridge returns wrong type: " + res.getClass());
                throw new BasicException(
                            "BasicBridge returns wrong type: " + res.getClass());
            }
        }

        PropertyValue result = (PropertyValue) res ;

        if ((result.Value instanceof String) && (((String)result.Value)).startsWith("Exception")) {
            throw new BasicException((String)result.Value);
        }

        return result;
    }

    /**
     * Returns true, if name is a supported service of this class.
     * @param name The service name.
     * @return True, if the service is supported.
     */
    public boolean supportsService(String name) {
        return serviceName.equals(name);
    }

    /**
     * Return all supported service names.
     * @return All supported services.
     */
    public String[] getSupportedServiceNames() {
        return new String[] {serviceName};
    }

    /**
     * Get the implementation name.
     * @return Implementation name.
     */
    public String getImplementationName() {
        return getClass().getName();
    }

    /** 
     * Create an instance of HandlerContainer.
     * Arguments are not supported here, so they will be ignored.
     * @param args The arguments.
     * @return The instance.
     */
    public Object createInstanceWithArguments(Object[] args) {
        return container;
    }

    /** 
     * Create an instance of HandlerContainer.
     * @return The instance.
     */
    public Object createInstance() {
        return createInstanceWithArguments(null);
    }

    /**
     * Dispose the BASIC document.
     */
    public synchronized void dispose() {
        try {
            if (oHandlerDoc != null) {
                //oHandlerDoc.dispose();
                util.DesktopTools.closeDoc(oHandlerDoc);
                wait(1000);
            }
        } catch (Exception e) {
            System.out.println("Exception: " + e.toString());
        }
    }
}


/**
 * This class handles the communication between Java and BASIC.
 * @see com.sun.star.container.XContainer
 * @see com.sun.star.container.XNameContainer
 * @see com.sun.star.lang.XTypeProvider
 */ 
class HandlerContainer implements XContainer, XNameContainer, XTypeProvider{

    /** Container for parameters.
     **/
    Hashtable container = new Hashtable(20);
    /**
     * An array of listeners for container events.
     * @see com.sun.star.container.XContainerListener
     */
    static XContainerListener[] listener = null;
    
    /** The BasicHandler belonging to this handler. **/
    BasicHandler parent = null;

    /**
     * Constructor with the parent BasicHandler.
     * @param par The BasicHandler. 
     */
    public HandlerContainer(BasicHandler par) {
        parent = par;
    }

    /**
     * Call a BASIC function, meaning a test method.
     * @param fName The method name.
     * @param args Arguments for the method.
     */
    public void callBasicFunction(String fName, Object args) {
        // BASIC's listener should be called ONLY in this case.
        if (container.containsKey(fName)) {
            container.remove(fName);
        }
        container.put(fName, args);
        if (listener != null) {
            ContainerEvent event = new ContainerEvent();
            event.Element = fName;
            for (int i=0; i<listener.length; i++){
                if (listener[i] != null) {
                    listener[i].elementInserted(event);
                }
            }
        }
    }

    /**
     * Insert an object into the container.
     * @param name The key for the object.
     * @param object The object to insert.
     * @throws IllegalArgumentException Throws this exception when trying to insert null.
     */
    public void insertByName(String name, Object object) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.container.ElementExistException, com.sun.star.lang.WrappedTargetException {

        // BASIC and Java can insert into the container.
        if (container.containsKey(name)) {
            container.remove(name);
        }
        container.put(name, object);

        PropertyValue result = null ;

        if (object instanceof PropertyValue) {
            result = (PropertyValue)object;
            if (name.equals("BASIC_Done")) {
                synchronized (parent) {
                    parent.notify();
                }
            } else if (name.equals("BASIC_MethodTested")) {
                parent.methodTested(result.Name, 
                                ((Boolean)result.Value).booleanValue());
            }
        } else if (name.equals("BASIC_Log")) {
            parent.Log(object.toString());
        }
    }

    /**
     * Remove the object with this name from the container.
     * @param name The key.
     */
    public void removeByName(String name) {
        container.remove(name) ;
    }

    /**
     * Unsupported method.
     * @param name The name of the key.
     * @param value The value.
     * @throws WrappedTargetException Throws this exception when called falsely.
     */
    public void replaceByName(String name, Object value)
                                          throws WrappedTargetException {
        throw new WrappedTargetException("Unsupported");
    }

    /**
     * Has a value for this key.
     * @param name The name of a key.
     * @return True, if name exists as key in the container.
     */
    public boolean hasByName(String name) {
        return container.containsKey(name);
    }

    /**
     * Get an object by its key.
     * @param name The name of the key.
     * @return The object of this key.
     */
    public Object getByName(String name) {
        return container.get(name);
    }

    /**
     * Get all key names.
     * @return All names of keys.
     */
    public String[] getElementNames() {
        String[] res = new String[container.size()];
        return (String[])container.keySet().toArray(res);
    }

    /**
     * Is the xcontainer empty?
     * @return True, if the container has elements.
     */
    public boolean hasElements() {
        return !container.isEmpty();
    }

    /**
     * Get the type of this class.
     * @return The type of this class.
     */
    public Type getElementType() {
        try {
            return new Type(String.class);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Get the implementation id of this class.
     * @return A unique id for this class
     * @see com.sun.star.lang.XTypeProvider
     */
    public byte[] getImplementationId() {
        return toString().getBytes();
    }

    /**
     * Get all types of this class.
     * @return All implemented UNO types.
     */
    public Type[] getTypes() {
        Class interfaces[] = getClass().getInterfaces();
        Type types[] = new Type[interfaces.length];
        for(int i = 0; i < interfaces.length; ++ i) {
            types[i] = new Type(interfaces[i]);
        }
        return types;
    }

    /**
     * Add a listener
     * @param xListener The listener.
     */
    public void addContainerListener(XContainerListener xListener){
        int length = 0;
        if (listener != null)
            length = listener.length;
        
        XContainerListener[] mListener = 
                        new XContainerListener[length+1];
        for (int i=0; i<length-1; i++) {
            mListener[i] = listener[i];
            // listener already added
            if (((Object)xListener).equals(listener[i]))
                return;
        }
        mListener[length] = xListener;
        listener = mListener;
    }

    /**
     * Remove a listener
     * @param xListener The listener.
     */
    public void removeContainerListener(XContainerListener xListener){
        if (listener != null && listener.length != 0) {
            int length = listener.length;
            XContainerListener[] mListener = 
                                    new XContainerListener[length-1];
            boolean found = false;
            int j=0;
            for (int i=0; i<length-1; i++) {
                if (!((Object)xListener).equals(listener[j])) {
                    mListener[i] = listener[j];
                }
                else {
                    j++;
                    found = true;
                }
                j++;
            }
            if (!found) {
                if (((Object)xListener).equals(listener[length-1]))
                    listener = mListener;
            }
            else
                listener = mListener;
                
        }
    }
}
