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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.List;
import java.util.Map;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import javolution.util.FastList;
import javolution.util.FastMap;

import org.ofbiz.base.component.ComponentConfig;
import org.ofbiz.base.container.Container;
import org.ofbiz.base.container.ContainerException;
import org.ofbiz.base.start.Classpath;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilURL;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.template.FreeMarkerWorker;
import org.w3c.dom.Document;

/**
 * GenerateContainer - Generates Configuration Files For Application Servers
 * ** This container requires StartInfoLoader to be loaded at startup.
 * ** This container requires the ComponentContainer to be loaded first.
 *
 */
public class GenerateContainer implements Container {

    public static final String module = GenerateContainer.class.getName();
    public static final String source = "/specialpurpose/appserver/templates/";
    public static String target = "/setup/";

    protected String configFile = null;
    protected String ofbizHome = null;
    protected String args[] = null;

    private boolean isGeronimo = false;
    private String geronimoHome = null;
    private String name;

    @Override
    public void init(String[] args, String name, String configFile) {
        this.name = name;
        ofbizHome = System.getProperty("ofbiz.home");
        this.configFile = configFile;
        this.args = args;
        isGeronimo = args[0].toLowerCase().contains("geronimo") || args[0].toLowerCase().contains("wasce");
        if (isGeronimo) {
            target="/META-INF/";
            geronimoHome = System.getenv("GERONIMO_HOME");
            if (geronimoHome == null) {
                geronimoHome = UtilProperties.getPropertyValue("appserver", "geronimoHome", null);
            }
        }
    }

    /**
     * @see org.ofbiz.base.container.Container#start()
     */
    public boolean start() throws ContainerException {
        generateFiles();
        return true;
    }

    /**
     * Stop the container
     *
     * @throws org.ofbiz.base.container.ContainerException
     *
     */
    public void stop() throws ContainerException {
    }

    public String getName() {
        return name;
    }

    private void generateFiles() throws ContainerException {
        if (isGeronimo) {
            if (geronimoHome == null) {
                Debug.logFatal("*** 'GERONIMO_HOME' was not found in your environment. Please set the location of Geronimo into a GERONIMO_HOME env var or as a geronimoHome property in appserver.properties file.", module);
                throw new ContainerException("Error in Geronimo deployment, please check the log");
            }
        }
        File files[] = getTemplates();
        Map<String, Object> dataMap = buildDataMap();

        String user = UtilProperties.getPropertyValue("appserver", "user", "system");
        String password = UtilProperties.getPropertyValue("appserver", "password", "manager");

        boolean offline = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "offline", "true");
        boolean redeploy = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "redeploy", "true");

        String geronimoHostHome = UtilProperties.getPropertyValue("appserver", "geronimoHostHome", null);
        String host = UtilProperties.getPropertyValue("appserver", "host", "");
        String port = UtilProperties.getPropertyValue("appserver", "port", "");
        boolean pauseInGeronimoScript = UtilProperties.propertyValueEqualsIgnoreCase("appserver", "pauseInGeronimoScript", "true");

        int instancesNumber = (int) UtilProperties.getPropertyNumber("appserver", "instancesNumber");
        String instanceNumber = "";

        if (isGeronimo) {
            File geronimoHomeDir = new File (geronimoHome);
            if (!(geronimoHomeDir.isDirectory())) {
                Debug.logFatal("*** " + geronimoHome + " does not exist or is not a directoy. Please set the location of Geronimo into a GERONIMO_HOME env var or as a geronimoHome property in appserver.properties file.", module);
                throw new ContainerException("Error in Geronimo deployment, please check the log");
            }

            if (UtilValidate.isNotEmpty(host) && UtilValidate.isNotEmpty(geronimoHostHome)) {
                geronimoHomeDir = new File ("//" + host + "/" + geronimoHostHome);
                if (!(geronimoHomeDir.isDirectory())) {
                    Debug.logFatal("*** " + geronimoHostHome + " does not exist or is not a directoy. Please set the location of Geronimo on host as a geronimoHostHome property in appserver.properties file.", module);
                    throw new ContainerException("Error in Geronimo deployment, please check the log");
                }
            } else {
                geronimoHostHome = geronimoHome;
            }

            if (redeploy && offline) {
                Debug.logFatal("*** You can't use redeploy with a server offline.", module);
                    throw new ContainerException("Error in Geronimo deployment, please check the log");
                }

            for (int inst = 0; inst <= instancesNumber; inst++) {
                instanceNumber = (inst == 0 ? "" : inst).toString();
                GenerateGeronimoDeployment geronimoDeployment = new GenerateGeronimoDeployment();
                List<String> classpathJars = geronimoDeployment.generate(args[0], geronimoHostHome, instanceNumber);
                if (classpathJars == null) {
                    throw new ContainerException("Error in Geronimo deployment, please check the log");
                }
                dataMap.put("classpathJars", classpathJars);
                dataMap.put("pathSeparatorChar", File.pathSeparatorChar);
                dataMap.put("instanceNumber", instanceNumber);
                //                if (UtilValidate.isNotEmpty(instanceNumber)) {
                //                    List webApps = (List) dataMap.get("webApps");
                //                    for (Object webAppObject: webApps) {
                //                        WebappInfo webAppInfo = (ComponentConfig.WebappInfo) webAppObject;
                //                        String webAppLocation = webAppInfo.getLocation();
                //                        String webXmlLocation = webAppLocation + "/WEB-INF/web.xml";
                //                        if (isFileExistsAndCanWrite(webXmlLocation)) {
                //                            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                //                            DocumentBuilder docBuilder = null;
                //                            try {
                //                                docBuilder = docFactory.newDocumentBuilder();
                //                            } catch (ParserConfigurationException e) {
                //                                throw new ContainerException(e);
                //                            }
                //                            Document doc = null;
                //                            try {
                //                                doc = docBuilder.parse(webXmlLocation);
                //                            } catch (SAXException e) {
                //                                throw new ContainerException(e);
                //                            } catch (IOException e) {
                //                                throw new ContainerException(e);
                //                            }
                //                            Node webApp = doc.getFirstChild();
                //                            Node contextParam = doc.createElement("context-param");
                //                            NamedNodeMap contextParamAttributes = contextParam.getAttributes();
                //
                //                            Attr paramName = doc.createAttribute("param-name");
                //                            paramName.setValue("instanceNumber");
                //                            contextParamAttributes.setNamedItem(paramName);
                //
                //                            Attr paramValue = doc.createAttribute("param-value");
                //                            paramValue.setValue(instanceNumber);
                //                            contextParamAttributes.setNamedItem(paramValue);
                //        //                    Node nodeToAppend = doc.importNode(contextParam, true); this should not be needed
                //        //                    webApp.appendChild(nodeToAppend);
                //
                //        //                    webApp.appendChild(contextParam); this is the line needed but commented for now
                //
                //                            Transformer transformer;
                //                            try {
                //                                transformer = TransformerFactory.newInstance().newTransformer();
                //                            } catch (TransformerConfigurationException e) {
                //                                throw new ContainerException(e);
                //                            } catch (TransformerFactoryConfigurationError e) {
                //                                throw new ContainerException(e);
                //                            }
                //                            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                //
                //                            StreamResult result = new StreamResult(new StringWriter());
                //                            DOMSource source = new DOMSource(doc);
                //                            try {
                //                                transformer.transform(source, result);
                //                            } catch (TransformerException e) {
                //                                throw new ContainerException(e);
                //                            }
                //                            String xmlString = result.getWriter().toString();
                //                            System.out.println(xmlString); //TODO write to file using writeToXmlFile
                //                            break; // Only the 1st web.xml file need to be modified
                //                        } else {
                //                            Debug.logInfo("Unable to change the deployment descriptor : " + webXmlLocation + ". Maybe it does not exist, or is in read only mode ?", module);
                //                        }
                //                    }
                //                }

                //Debug.logInfo("Using Data : " + dataMap, module);
                for (int i = 0; i < files.length; i++) {
                    if (!(files[i].isDirectory() || files[i].isHidden() || files[i].getName().equalsIgnoreCase("geronimo-web.xml"))) {
                        parseTemplate(files[i], dataMap);
                    }
                }

                String ofbizName = "ofbiz" + instanceNumber;
                String separator = File.separator;
                File workingDir = new File(geronimoHome + separator + "bin");
                ProcessBuilder processBuilder = null;
                Process process = null;
                String command = null;
                String commandCommonPart = null;
                if ("\\".equals(separator)) {   //Windows
                    commandCommonPart = "deploy --user " + user +  " --password " +  password;
                } else {                        // Linux
                    commandCommonPart = workingDir + "/deploy.sh --user " + user +  " --password " +  password;
                }
                if (UtilValidate.isNotEmpty(host)) {
                    commandCommonPart += " --host " + host + (UtilValidate.isNotEmpty(port) ? " --port " + port : "");
                }

                if (!redeploy) {
                if ("\\".equals(separator)) { //Windows
                    if (offline) {
                        command = commandCommonPart + " --offline undeploy " + ofbizName;
                    } else {
                        command = commandCommonPart + " undeploy " + ofbizName;
                    }
                        processBuilder = new ProcessBuilder("cmd.exe", "/c", command);
                } else {                        // Linux
                    if (offline) {
                        command = commandCommonPart + " --offline undeploy " + ofbizName;
                    } else {
                        command = commandCommonPart + " undeploy " + ofbizName;
                    }
                        processBuilder = new ProcessBuilder("sh", "-c", command);
                }

                if (pauseInGeronimoScript) {
                        Map<String, String> env = processBuilder.environment();
                    env.put("GERONIMO_BATCH_PAUSE", "on");
                }
                    processBuilder.directory(workingDir);

                try {
                    System.out.println("Currently undeploying " + ofbizName + ", using : <<" + command + ">>, please wait ...");
                        processBuilder.redirectErrorStream(true);
                        process = processBuilder.start();
                        java.io.InputStream is = process.getInputStream();
                    byte[] buf = new byte[2024];
                    int readLen = 0;
                    while ((readLen = is.read(buf,0,buf.length)) != -1) {
                        if ("\\".equals(separator)) {   //Windows
                            System.out.print(new String(buf,0,readLen));
                        } else {
                            System.out.println(new String(buf,0,readLen));
                        }
                    }
                    is.close();
                        process.waitFor();
    //                    System.out.println(process.waitFor());
    //                    System.out.println("exit value" + process.exitValue());
                    Debug.logInfo(ofbizName + " undeployment ended" , module);
                } catch (IOException e) {
                    throw new ContainerException(e);
                } catch (InterruptedException e) {
                    throw new ContainerException(e);
                    } finally {
                        process.destroy();
                    }
                }

                if (redeploy) {
                    if ("\\".equals(separator)) { //Windows
                        command = commandCommonPart + " redeploy " + ofbizHome;
                        processBuilder = new ProcessBuilder("cmd.exe", "/c", command);
                    } else {                      // Linux
                        command = commandCommonPart + " redeploy " + ofbizHome;
                        processBuilder = new ProcessBuilder("sh", "-c", command);
                }

                } else {
                if ("\\".equals(separator)) { //Windows
                    if (offline) {
                            command = commandCommonPart + " --offline deploy --inPlace " + ofbizHome;
                    } else {
                            command = commandCommonPart + " deploy --inPlace " + ofbizHome;
                    }
                        processBuilder = new ProcessBuilder("cmd.exe", "/c", command);
                } else {                      // Linux
                    if (offline) {
                            command = commandCommonPart + " --offline deploy --inPlace " + ofbizHome;
                    } else {
                            command = commandCommonPart + " deploy --inPlace " + ofbizHome;
                        }
                        processBuilder = new ProcessBuilder("sh", "-c", command);
                    }
                }

                if (pauseInGeronimoScript) {
                    Map<String, String> env = processBuilder.environment();
                    env.put("GERONIMO_BATCH_PAUSE", "on");
                }
                processBuilder.directory(workingDir);

                try {
                    System.out.println("Currently deploying " + ofbizName + ", using : <<" + command + ">>, please wait ...");
                    processBuilder.redirectErrorStream(true);
                    process = processBuilder.start();
                    java.io.InputStream is = process.getInputStream();
                    byte[] buf = new byte[2024];
                    int readLen = 0;
                    while ((readLen = is.read(buf,0,buf.length)) != -1) {
                        if ("\\".equals(separator)) {   //Windows
                            System.out.print(new String(buf,0,readLen));
                        } else {
                            System.out.println(new String(buf,0,readLen));
                        }
                    }
                    is.close();
                    process.waitFor();
//                    System.out.println(process.waitFor());
//                    System.out.println("exit value" + process.exitValue());
                    Debug.logInfo(ofbizName + " deployment ended" , module);
                } catch (IOException e) {
                    throw new ContainerException(e);
                } catch (InterruptedException e) {
                    throw new ContainerException(e);
                } finally {
                    process.destroy();
                }
            }
        } else {
            //Debug.logInfo("Using Data : " + dataMap, module);
            for (int i = 0; i < files.length; i++) {
                if (!files[i].isDirectory() && !files[i].isHidden()) {
                    parseTemplate(files[i], dataMap);
                }
            }
        }
    }

    private File[] getTemplates() throws ContainerException {
        if (args == null) {
            throw new ContainerException("Invalid application server type argument passed");
        }

        String templateLocation = args[0];
        if (templateLocation == null) {
            throw new ContainerException("Unable to locate Application Server template directory");
        }

        File parentDir = new File(ofbizHome + source + templateLocation);
        if (!parentDir.exists() || !parentDir.isDirectory()) {
            throw new ContainerException("Template location - " + templateLocation + " does not exist!");
        }

        return parentDir.listFiles();
    }

    private Map<String, Object> buildDataMap() throws ContainerException {
        Map<String, Object> dataMap = FastMap.newInstance();
        List<?> c[] = getClasspath();
        dataMap.put("targetDirectory", getTargetDirectory());
        dataMap.put("pathSeparatorChar", File.pathSeparatorChar);
        dataMap.put("classpath", System.getProperty("java.class.path"));
        dataMap.put("classpathJars", c[0]);
        dataMap.put("classpathDirs", c[1]);
        dataMap.put("env", System.getProperties());
        dataMap.put("webApps", ComponentConfig.getAllWebappResourceInfos());
        dataMap.put("ofbizHome", System.getProperty("ofbiz.home"));
        return dataMap;
    }

    private List<?>[] getClasspath() {
        Classpath classPath = new Classpath(System.getProperty("java.class.path"));
        List<File> elements = classPath.getElements();
        List<String> jar = FastList.newInstance();
        List<String> dir = FastList.newInstance();

        for (File f: elements) {
            if (f.exists()) {
                if (f.isDirectory()) {
                    String path = f.getAbsolutePath();
                    dir.add(path.replace('\\','/'));
                } else {
                    String path = f.getAbsolutePath();
                    jar.add(path.replace('\\','/'));
                }
            }
        }
        List<?>[] lists = { jar, dir };
        return lists;
    }

    private String getTargetDirectory() throws ContainerException {
        // create the target file/directory
        String targetDirectoryName = args.length > 1 ? args[1] : null;
        if (targetDirectoryName == null) {
            targetDirectoryName = target;
        }
        String targetDirectory = null;
        if (!isGeronimo) {
            targetDirectory = ofbizHome + targetDirectoryName + args[0];
        } else {
            targetDirectory = ofbizHome + targetDirectoryName;
        }
        File targetDir = new File(targetDirectory);
        if (!targetDir.exists()) {
            boolean created = targetDir.mkdirs();
            if (!created) {
                throw new ContainerException("Unable to create target directory - " + targetDirectory);
            }
        }

        if (!targetDirectory.endsWith("/")) {
            targetDirectory = targetDirectory + "/";
        }

        return targetDirectory;
    }

    private void parseTemplate(File templateFile, Map<String, Object> dataMap) throws ContainerException {
        Debug.logInfo("Parsing template : " + templateFile.getAbsolutePath(), module);
        Reader reader = null;
        try {
            reader = new InputStreamReader(new FileInputStream(templateFile));
        } catch (FileNotFoundException e) {
            throw new ContainerException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    throw new ContainerException(e);
                }
            }
        }

        // create the target file/directory
        String targetDirectory = getTargetDirectory();

        // write the template to the target directory
        Writer writer = null;
        try {
            writer = new FileWriter(targetDirectory + templateFile.getName());
            try {
                FreeMarkerWorker.renderTemplate(UtilURL.fromFilename(templateFile.getAbsolutePath()).toExternalForm(), dataMap, writer);
            } catch (Exception e) {
                throw new ContainerException(e);
            }
        } catch (IOException e) {
            throw new ContainerException(e);
        } finally {
            try {
                if (writer != null) {
                    writer.flush();
                    writer.close();
                }
            } catch (IOException e) {
                throw new ContainerException(e);
            }
        }

    }

    // This method writes a DOM document to a file
    public static void writeToXmlFile(Document doc, String filename) {
        try {
            // Prepare the DOM document for writing
            Source source = new DOMSource(doc);

            // Prepare the output file
            File file = new File(filename);
            Result result = new StreamResult(file);

            // Write the DOM document to the file
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
        } catch (TransformerException e) {
        }
    }

    public boolean isFileExistsAndCanWrite(String fileName) {
        File f = new File(fileName);
        return f.exists() && f.canWrite();
    }
}
