/* 
 * 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.felix.sandbox.obr.plugin;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
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 org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * this class parse the old repository.xml file build the bundle resource description and update the repository.
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */

public class ObrUpdate {
    /**
     * generate the date format to insert it in repository descriptor file.
     */
    static SimpleDateFormat m_format = new SimpleDateFormat("yyyyMMddHHmmss.SSS");

    /**
     * logger for this plugin.
     */
    private Log m_logger;

    /**
     * name and path to the repository descriptor file.
     */
    private URI m_repoFilename;

    /**
     * name and path to the obr.xml file.
     */
    private String m_obrXml;

    /**
     * name and path to the bundle jar file.
     */
    private String m_outputFile;

    /**
     * maven project description.
     */
    private MavenProject m_project;

    /**
     * user configuration information.
     */
    private Config m_userConfig;

    /**
     * used to build another xml document.
     */
    private DocumentBuilder m_constructor;

    /**
     * root on parent document.
     */
    private Document m_repoDoc;

    /**
     * used to determine the first free id.
     */
    private boolean[] m_idTab;

    /**
     * first Node on repository descriptor tree.
     */
    private Node m_root;

    /**
     * used to extract bindex bundle information.
     */
    private ExtractBindexInfo m_ebi;

    /**
     * used to store bundle information.
     */
    private ResourcesBundle m_resourceBundle;

    /**
     * pathfile to the repository descriptor file.
     */
    private PathFile m_repo;

    /**
     * initialize information.
     * @param repoFilename path to the repository descriptor file
     * @param obrXml path and filename to the obr.xml file
     * @param project maven project description
     * @param outputFile path to the bundle jar file
     * @param localRepo only path to the local repository
     * @param userConfig user information
     * @param log plugin logger
     */
    public ObrUpdate(PathFile repoFilename, String obrXml, MavenProject project, String outputFile, String localRepo, Config userConfig, Log log) {
        // this.m_localRepo = localRepo;
        this.m_outputFile = outputFile;
        this.m_repoFilename = repoFilename.getUri();
        this.m_obrXml = obrXml;
        this.m_project = project;
        this.m_logger = log;

        this.m_userConfig = userConfig;
        // init the tab
        m_idTab = new boolean[0];

        m_resourceBundle = new ResourcesBundle(log);

        if (userConfig.isRemotely()) {
            this.m_repo = new PathFile(localRepo);
        } else {
            this.m_repo = repoFilename;
        }
        // System.err.println("Construct: "+repoFilename.getAbsoluteFilename());
    }

    /**
     * update the repository descriptor file. parse the old repository descriptor file, get the old reference of the bundle or determine the id for a new bundle, extract information from bindex set the new information in descriptor file and save it.
     * @throws MojoExecutionException if the plugin failed
     */
    public void updateRepository() throws MojoExecutionException {
    	
    	m_logger.debug(" (f) m_obrXml = " + m_obrXml);
    	m_logger.debug(" (f) m_outputFile = " + m_outputFile);
    	m_logger.debug(" (f) m_repoFilename = " + m_repoFilename);

        m_constructor = initConstructor();

        if (m_constructor == null)  {
            return;
        }

        // get the file size
        PathFile pf = new PathFile(m_outputFile);
        File fout = pf.getFile();
        pf.setBaseDir(m_repo.getOnlyAbsolutePath());
        if (fout.exists()) {
            m_resourceBundle.setSize(String.valueOf(fout.length()));
            if (m_userConfig.isPathRelative()) {
                m_resourceBundle.setUri(pf.getOnlyRelativeFilename().replace('\\', '/'));
            } else {
                m_resourceBundle.setUri("file:" + m_outputFile);
            }
        } else {
            m_logger.error("file doesn't exist: " + m_outputFile);
            return;
        }

        // parse repository
        if (parseRepositoryXml() == -1) { return; }

        // parse the obr.xml file
        if (m_obrXml != null) {
            // URL url = getClass().getResource("/SchemaObr.xsd");
            // TODO validate obr.xml file

            Document obrXmlDoc = parseFile(m_obrXml, m_constructor);
            if (obrXmlDoc == null) { return; }
            Node obrXmlRoot = (Element) obrXmlDoc.getDocumentElement();
            // sort the obr file
            sortObrXml(obrXmlRoot);
        }

        // use bindex to extract bundle information
        try {
            m_ebi = new ExtractBindexInfo(m_repoFilename, m_outputFile);
        } catch (MojoExecutionException e) {
            m_logger.error("unable to build Bindex informations");
            e.printStackTrace();
            throw new MojoExecutionException("MojoFailureException");
        }

        m_resourceBundle.construct(m_project, m_ebi);

        if (!walkOnTree(m_root)) {
            // the correct resource node was not found, we must create it
            // we calcul the new id
            int id = -1;
            for (int i = 1; i < m_idTab.length; i++) {
                if (!m_idTab[i]) {
                    id = i;
                    break;
                }
            }
            if (id == -1) { id = m_idTab.length; }

            searchRepository(m_root, id);
        }

        // the repository.xml file have been modified, so we save it
        writeToFile(m_repoFilename, m_root);
    }

    /**
     * init the document builder from xerces.
     * @return DocumentBuilder ready to create new document
     */
    private DocumentBuilder initConstructor() {
        DocumentBuilder constructor = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            constructor = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            m_logger.error("unable to create a new xml document");
            e.printStackTrace();
        }
        return constructor;

    }

    /**
     * Parse the reporitory descriptor file.
     * 
     * @return 0 if the bundle is already in the descriptor, else -1
     * @throws MojoExecutionException if the plugin failed
     */
    private int parseRepositoryXml() throws MojoExecutionException {

        File fout = new File(m_repoFilename);
        if (!fout.exists()) {
            // create the repository.xml
            try {

            	fout.createNewFile();
                m_logger.info("Created new repository.xml file in "+fout.getAbsolutePath());
            } catch (IOException e) {
                m_logger.error("Cannot create file " + fout.getAbsolutePath());
                e.printStackTrace();
                return -1;
            }

            Document doc = m_constructor.newDocument();
            // create xml tree
            Date d = new Date();
            d.setTime(System.currentTimeMillis());
            Element root = doc.createElement("repository");
            root.setAttribute("lastmodified", m_format.format(d));
            root.setAttribute("name", "MyRepository");
            try {
                writeToFile(m_repoFilename, root);
            } catch (MojoExecutionException e) {
                e.printStackTrace();
                throw new MojoExecutionException("MojoExecutionException");
            }
        }

        // now we parse the repository.xml file
        m_repoDoc = parseFile(fout.getAbsolutePath(), m_constructor);
        if (m_repoDoc == null) { return -1; }

        m_root = (Element) m_repoDoc.getDocumentElement();
        return 0;

    }

    /**
     * transform a xml file to a xerces Document.
     * @param filename path to the xml file
     * @param constructor DocumentBuilder get from xerces
     * @return Document which describe this file
     */
    private Document parseFile(String filename, DocumentBuilder constructor) {
        if (constructor == null) { return null; }
        // The document is the root of the DOM tree.
        m_logger.info("Try to open: " + filename);
        Document doc = null;
        try {
            doc = constructor.parse(new File(filename));
        } catch (SAXException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            m_logger.error("cannot open file: " + filename);
            e.printStackTrace();
            return null;
        }
        return doc;
    }

    /**
     * put the information from obr.xml into ressourceBundle object.
     * @param node Node to the OBR.xml file
     */
    private void sortObrXml(Node node) {
        if (node.getNodeName().compareTo("require") == 0) {
            Require newRequireNode = new Require();
            NamedNodeMap list = node.getAttributes();
            try {
                newRequireNode.setExtend(list.getNamedItem("extend").getNodeValue());
                newRequireNode.setMultiple(list.getNamedItem("multiple").getNodeValue());
                newRequireNode.setOptional(list.getNamedItem("optional").getNodeValue());
                newRequireNode.setFilter(list.getNamedItem("filter").getNodeValue());
                newRequireNode.setName(list.getNamedItem("name").getNodeValue());
            } catch (NullPointerException e) {
                m_logger.error("the obr.xml file seems to be invalid in a \"require\" tag (one or more attributes are missing)");
                // e.printStackTrace();
            }
            newRequireNode.setValue(XmlHelper.getTextContent(node));
            m_resourceBundle.addRequire(newRequireNode);
        } else if (node.getNodeName().compareTo("capability") == 0) {
            Capability newCapability = new Capability();
            try {
                newCapability.setName(node.getAttributes().getNamedItem("name").getNodeValue());
            } catch (NullPointerException e) {
                m_logger.error("attribute \"name\" is missing in obr.xml in a \"capability\" tag");
                e.printStackTrace();
            }
            NodeList list = node.getChildNodes();
            for (int i = 0; i < list.getLength(); i++) {
                PElement p = new PElement();
                Node n = list.item(i);
                Node item = null;
                // System.err.println(n.getNodeName());
                if (n.getNodeName().compareTo("p") == 0) {

                    p.setN(n.getAttributes().getNamedItem("n").getNodeValue());
                    item = n.getAttributes().getNamedItem("t");
                    if (item != null) { p.setT(item.getNodeValue()); }
                    item = n.getAttributes().getNamedItem("v");
                    if (item != null) { p.setV(item.getNodeValue()); }

                    newCapability.addP(p);
                }
            }
            m_resourceBundle.addCapability(newCapability);
        } else if (node.getNodeName().compareTo("category") == 0) {
            Category newCategory = new Category();
            newCategory.setId(node.getAttributes().getNamedItem("id").getNodeValue());
            m_resourceBundle.addCategory(newCategory);
        } else {
            NodeList list = node.getChildNodes();
            for (int i = 0; i < list.getLength(); i++) {
                sortObrXml(list.item(i));
            }
        }
    }

    /**
     * write a Node in a xml file.
     * @param outputFilename URI to the output file
     * @param treeToBeWrite Node root of the tree to be write in file
     * @throws MojoExecutionException if the plugin failed
     */
    private void writeToFile(URI outputFilename, Node treeToBeWrite) throws MojoExecutionException {
        // init the transformer
        Transformer transformer = null;
        TransformerFactory tfabrique = TransformerFactory.newInstance();
        try {
            transformer = tfabrique.newTransformer();
        } catch (TransformerConfigurationException e) {
            m_logger.error("Unable to write to file: " + outputFilename.toString());
            e.printStackTrace();
            throw new MojoExecutionException("TransformerConfigurationException");
        }
        Properties proprietes = new Properties();
        proprietes.put("method", "xml");
        proprietes.put("version", "1.0");
        proprietes.put("encoding", "ISO-8859-1");
        proprietes.put("standalone", "yes");
        proprietes.put("indent", "yes");
        proprietes.put("omit-xml-declaration", "no");
        transformer.setOutputProperties(proprietes);

        DOMSource input = new DOMSource(treeToBeWrite);

        File fichier = new File(outputFilename);
        FileOutputStream flux = null;
        try {
            flux = new FileOutputStream(fichier);
        } catch (FileNotFoundException e) {
            m_logger.error("Unable to write to file: " + fichier.getName());
            e.printStackTrace();
            throw new MojoExecutionException("FileNotFoundException");
        }
        Result output = new StreamResult(flux);
        try {
            transformer.transform(input, output);
        } catch (TransformerException e) {
            e.printStackTrace();
            throw new MojoExecutionException("TransformerException");
        }

        try {
            flux.flush();
            flux.close();
        } catch (IOException e) {
            e.printStackTrace();
            throw new MojoExecutionException("IOException");
        }

    }

    /**
     * walk on the tree until the targeted node was found.
     * @param node targeted node
     * @return true if the requiered node was found else false.
     */
    private boolean walkOnTree(Node node) {

        if (node.getNodeName().compareTo("resource") == 0) {
            return resource(node);
        } else { // look at the repository node (first in the file)
            if (node.getNodeName().compareTo("repository") == 0) {
                Date d = new Date();
                d.setTime(System.currentTimeMillis());
                NamedNodeMap nList = node.getAttributes();
                Node n = nList.getNamedItem("lastmodified");
                n.setNodeValue(m_format.format(d));
            }
            NodeList list = node.getChildNodes();
            if (list.getLength() > 0) {
                for (int i = 0; i < list.getLength(); i++) {
                    if (walkOnTree(list.item(i))) { return true; }
                }
            }
            return false;
        }

    }

    /**
     * put the resource bundle in the tree.
     * @param node Node on the xml file
     * @param id id of the bundle ressource
     */
    private void searchRepository(Node node, int id) {
        if (node.getNodeName().compareTo("repository") == 0) {
            m_resourceBundle.setId(String.valueOf(id));
            node.appendChild(m_resourceBundle.getNode(m_repoDoc));
            return;
        } else {
            NodeList list = node.getChildNodes();
            if (list.getLength() > 0) {
                for (int i = 0; i < list.getLength(); i++) {
                    searchRepository(list.item(i), id);
                }
            }
        }

    }

    /**
     * compare two node and update the array which compute the smallest free id.
     * @param node : node
     * @return true if the node is the same bundle than the ressourceBundle, else false.
     */
    private boolean resource(Node node) {

        // this part save all the id free if we need to add resource
        int id = Integer.parseInt(node.getAttributes().getNamedItem("id").getNodeValue());
        if (id >= m_idTab.length) {
            // resize tab
            boolean[] bt = new boolean[id + 1];
            for (int i = 0; i < id + 1; i++) {
                if (m_idTab.length > i && m_idTab[i]) {
                    bt[i] = true;
                } else {
                    bt[i] = false;
                }
            }

            m_idTab = bt;
        }
        m_idTab[id] = true;

        NamedNodeMap map = node.getAttributes();

        if (m_resourceBundle.isSameBundleResource(map.getNamedItem("symbolicname").getNodeValue(), map.getNamedItem("presentationname").getNodeValue(), map.getNamedItem("version").getNodeValue())) {
            m_resourceBundle.setId(String.valueOf(id));
            node.getParentNode().replaceChild(m_resourceBundle.getNode(m_repoDoc), node);
            return true;
        }
        return false;
    }
}
