/*******************************************************************************
 * 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.ofbiz.content.openoffice;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.container.XNameAccess;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uri.ExternalUriReferenceTranslator;

/**
 * OpenOfficeWorker Class
 *
 * Note that for this to work you must start OpenOffice with a command such as the following:
 *   <code>soffice -accept=socket,host=localhost,port=8100;urp;</code>
 */
public class OpenOfficeWorker{

    public static final String module = OpenOfficeWorker.class.getName();

    /**
     * Use OpenOffice to convert documents between types
     */
    public static XMultiComponentFactory getRemoteServer(String host, String port) throws IOException, Exception {

        if (UtilValidate.isEmpty(host)) host = UtilProperties.getPropertyValue("openoffice-uno", "oo.host", "localhost");
        if (UtilValidate.isEmpty(port)) port = UtilProperties.getPropertyValue("openoffice-uno", "oo.port", "8100");

        XMultiComponentFactory xmulticomponentfactory = null;
        XComponentContext xcomponentcontext = null;
        Object objectUrlResolver = null;
        XUnoUrlResolver xurlresolver = null;
        Object objectInitial = null;
        // Converting the document to the favoured type
        try {
            /* Bootstraps a component context with the jurt base components
            registered. Component context to be granted to a component for running.
            Arbitrary values can be retrieved from the context. */
            xcomponentcontext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);

            /* Gets the service manager instance to be used (or null). This method has
            been added for convenience, because the service manager is a often used
            object. */
            xmulticomponentfactory = xcomponentcontext.getServiceManager();

            /* Creates an instance of the component UnoUrlResolver which
            supports the services specified by the factory. */
            objectUrlResolver = xmulticomponentfactory.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", xcomponentcontext);

            // Create a new url resolver
            xurlresolver = (XUnoUrlResolver) UnoRuntime.queryInterface(XUnoUrlResolver.class, objectUrlResolver);

            // Resolves an object that is specified as follow:
            // uno:<connection description>;<protocol description>;<initial object name>
            String url = "uno:socket,host=" + host + ",port=" + port + ";urp;StarOffice.ServiceManager";
            objectInitial = xurlresolver.resolve(url);

            // Create a service manager from the initial object
            xmulticomponentfactory = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class, objectInitial);
        } catch (Exception e) {
            // TODO: None of this works. Need a programmable start solution.
            //String ooxvfb = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.xvfb");
            //String ooexport = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.export");
           // String oosoffice = UtilProperties.getPropertyValue("openoffice-uno", "oo.start.soffice");
            //Process procXvfb = Runtime.getRuntime().exec(ooxvfb);
            //Process procExport = Runtime.getRuntime().exec(ooexport);
            /*
            Process procSoffice = Runtime.getRuntime().exec(oosoffice);
            Thread.sleep(3000);
            objectInitial = xurlresolver.resolve("uno:socket,host=" + host + ",port=" + port + ";urp;StarOffice.ServiceManager");
            xmulticomponentfactory = (XMultiComponentFactory) UnoRuntime.queryInterface(XMultiComponentFactory.class, objectInitial);
            Debug.logInfo("soffice started. " + procSoffice, module);
            */
            String errMsg = "Error connecting to OpenOffice with host [" + host + "] and port [" + port + "]: " + e.toString();
            Debug.logError(e, errMsg, module);
            throw new IllegalArgumentException(errMsg);
        }

        return xmulticomponentfactory;
    }

    public static String listFilterNamesEvent(HttpServletRequest request, HttpServletResponse response) {
        XMultiComponentFactory factory = null;

        try {
            factory = getRemoteServer("localhost", "8100");
            List filterList = getFilterNames(factory);
            request.setAttribute("filterList", filterList);
        } catch (IOException e) {
            request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
            return "error";
        } catch (Exception e) {
            request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
            return "error";
        }
        return "success";
    }

    public static List getFilterNames(XMultiComponentFactory xmulticomponentfactory) throws Exception {
        XPropertySet xPropertySet = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xmulticomponentfactory);
        Object oDefaultContext = xPropertySet.getPropertyValue("DefaultContext");
        XComponentContext xComponentContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, oDefaultContext);


        Object filterFactory = xmulticomponentfactory.createInstanceWithContext("com.sun.star.document.FilterFactory", xComponentContext);
        XNameAccess xNameAccess = (XNameAccess)UnoRuntime.queryInterface(XNameAccess.class, filterFactory);
        String [] filterNames = xNameAccess.getElementNames();

        //String [] serviceNames = filterFactory.getAvailableServiceNames();
        for (int i=0; i < filterNames.length; i++) {
            String s = filterNames[i];
            Debug.logInfo(s, module);
            /*
            if (s.toLowerCase().indexOf("filter") >= 0) {
                Debug.logInfo("FILTER: " + s, module);
            }
            if (s.toLowerCase().indexOf("desktop") >= 0) {
                Debug.logInfo("DESKTOP: " + s, module);
            }
            */
        }

        List filterNameList = UtilMisc.toListArray(filterNames);
        return filterNameList;
    }

    public static void convertOODocToFile(XMultiComponentFactory xmulticomponentfactory, String fileInPath, String fileOutPath, String outputMimeType) throws FileNotFoundException, IOException, MalformedURLException, Exception {
        // Converting the document to the favoured type
        // Query for the XPropertySet interface.
        XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xmulticomponentfactory);

        // Get the default context from the office server.
        Object objectDefaultContext = xpropertysetMultiComponentFactory.getPropertyValue("DefaultContext");

        // Query for the interface XComponentContext.
        XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, objectDefaultContext);

        /* A desktop environment contains tasks with one or more
           frames in which components can be loaded. Desktop is the
           environment for components which can instanciate within
           frames. */

        Object desktopObj = xmulticomponentfactory.createInstanceWithContext("com.sun.star.frame.Desktop", xcomponentcontext);
        //XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktopObj);
        XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktopObj);


        // Preparing properties for loading the document
        PropertyValue propertyvalue[] = new PropertyValue[ 2 ];
        // Setting the flag for hidding the open document
        propertyvalue[ 0 ] = new PropertyValue();
        propertyvalue[ 0 ].Name = "Hidden";
        propertyvalue[ 0 ].Value = Boolean.valueOf(false);

        propertyvalue[ 1 ] = new PropertyValue();
        propertyvalue[ 1 ].Name = "UpdateDocMode";
        propertyvalue[ 1 ].Value = "1";

        // Loading the wanted document
        String stringUrl = convertToUrl(fileInPath, xcomponentcontext);
        Debug.logInfo("stringUrl:" + stringUrl, module);
        Object objectDocumentToStore = xcomponentloader.loadComponentFromURL(stringUrl, "_blank", 0, propertyvalue);

        // Getting an object that will offer a simple way to store a document to a URL.
        XStorable xstorable = (XStorable) UnoRuntime.queryInterface(XStorable.class, objectDocumentToStore);

        // Preparing properties for converting the document
        propertyvalue = new PropertyValue[ 3 ];
        // Setting the flag for overwriting
        propertyvalue[ 0 ] = new PropertyValue();
        propertyvalue[ 0 ].Name = "Overwrite";
        propertyvalue[ 0 ].Value = Boolean.valueOf(true);
        // Setting the filter name
        // Preparing properties for converting the document
        String filterName = getFilterNameFromMimeType(outputMimeType);

        propertyvalue[ 1 ] = new PropertyValue();
        propertyvalue[ 1 ].Name = "FilterName";
        propertyvalue[ 1 ].Value = filterName;

        propertyvalue[2] = new PropertyValue();
        propertyvalue[2].Name = "CompressionMode";
        propertyvalue[2].Value = "1";

        // Storing and converting the document
        //File newFile = new File(stringConvertedFile);
        //newFile.createNewFile();

        String stringConvertedFile = convertToUrl(fileOutPath, xcomponentcontext);
        Debug.logInfo("stringConvertedFile: "+stringConvertedFile, module);
        xstorable.storeToURL(stringConvertedFile, propertyvalue);

        // Getting the method dispose() for closing the document
        XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xstorable);

        // Closing the converted document
        xcomponent.dispose();
        return;
    }

    public static OpenOfficeByteArrayOutputStream convertOODocByteStreamToByteStream(XMultiComponentFactory xmulticomponentfactory,
            OpenOfficeByteArrayInputStream is, String inputMimeType, String outputMimeType) throws Exception {

        // Query for the XPropertySet interface.
        XPropertySet xpropertysetMultiComponentFactory = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xmulticomponentfactory);

        // Get the default context from the office server.
        Object objectDefaultContext = xpropertysetMultiComponentFactory.getPropertyValue("DefaultContext");

        // Query for the interface XComponentContext.
        XComponentContext xcomponentcontext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, objectDefaultContext);

        /* A desktop environment contains tasks with one or more
           frames in which components can be loaded. Desktop is the
           environment for components which can instanciate within
           frames. */

        Object desktopObj = xmulticomponentfactory.createInstanceWithContext("com.sun.star.frame.Desktop", xcomponentcontext);
        //XDesktop desktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktopObj);
        XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, desktopObj);

        // Preparing properties for loading the document
        PropertyValue propertyvalue[] = new PropertyValue[2];
        // Setting the flag for hidding the open document
        propertyvalue[0] = new PropertyValue();
        propertyvalue[0].Name = "Hidden";
        propertyvalue[0].Value = Boolean.TRUE;
        //
        propertyvalue[1] = new PropertyValue();
        propertyvalue[1].Name = "InputStream";
        propertyvalue[1].Value = is;

        // Loading the wanted document
        Object objectDocumentToStore = xcomponentloader.loadComponentFromURL("private:stream", "_blank", 0, propertyvalue);
        if (objectDocumentToStore == null) {
            Debug.logError("Could not get objectDocumentToStore object from xcomponentloader.loadComponentFromURL", module);
        }

        // Getting an object that will offer a simple way to store a document to a URL.
        XStorable xstorable = (XStorable) UnoRuntime.queryInterface(XStorable.class, objectDocumentToStore);
        if (xstorable == null) {
            Debug.logError("Could not get XStorable object from UnoRuntime.queryInterface", module);
        }

        // Preparing properties for converting the document
        String filterName = getFilterNameFromMimeType(outputMimeType);
        propertyvalue = new PropertyValue[4];

        propertyvalue[0] = new PropertyValue();
        propertyvalue[0].Name = "OutputStream";
        OpenOfficeByteArrayOutputStream os = new OpenOfficeByteArrayOutputStream();
        propertyvalue[0].Value = os;
        // Setting the filter name
        propertyvalue[1] = new PropertyValue();
        propertyvalue[1].Name = "FilterName";
        propertyvalue[1].Value = filterName;
        // Setting the flag for overwriting
        propertyvalue[3] = new PropertyValue();
        propertyvalue[3].Name = "Overwrite";
        propertyvalue[3].Value = Boolean.TRUE;
        // For PDFs
        propertyvalue[2] = new PropertyValue();
        propertyvalue[2].Name = "CompressionMode";
        propertyvalue[2].Value = "1";

        xstorable.storeToURL("private:stream", propertyvalue);
        //xstorable.storeToURL("file:///home/byersa/testdoc1_file.pdf", propertyvalue);

        // Getting the method dispose() for closing the document
        XComponent xcomponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xstorable);

        // Closing the converted document
        xcomponent.dispose();

        return os;
    }

    public static String getFilterNameFromMimeType(String mimeType) {
        String filterName = "";
        if (UtilValidate.isEmpty(mimeType)) {
            filterName = "HTML";
        } else if (mimeType.equalsIgnoreCase("application/pdf")) {
            filterName = "writer_pdf_Export";
        } else if (mimeType.equalsIgnoreCase("application/msword")) {
            filterName = "MS Word 97";
        } else if (mimeType.equalsIgnoreCase("text/html")) {
            filterName = "HTML (StarWriter)";
        } else {
            filterName = "HTML";
        }
        return filterName;

    }

    public static String getExtensionFromMimeType(String mimeType) {
        String extension = "";
        if (UtilValidate.isEmpty(mimeType)) {
            extension = "html";
        } else if (mimeType.equalsIgnoreCase("application/pdf")) {
            extension = "pdf";
        } else if (mimeType.equalsIgnoreCase("application/msword")) {
            extension = "doc";
        } else if (mimeType.equalsIgnoreCase("text/html")) {
            extension = "html";
        } else {
            extension = "html";
        }
        return extension;

    }
    public static String convertToUrl(String filePath, XComponentContext xComponentContext) throws MalformedURLException {

        String returnUrl = null;
        File f = new File(filePath);
        URL u = f.toURL();
        returnUrl =  ExternalUriReferenceTranslator.create(xComponentContext).translateToInternal(u.toExternalForm());

        return returnUrl;
    }

}
