/**
 * 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.cxf.maven_plugin.xml2fastinfoset;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.sonatype.plexus.build.incremental.BuildContext;
import org.xml.sax.SAXException;

import com.sun.xml.fastinfoset.sax.SAXDocumentSerializer;

import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.Scanner;

/**
 * Compile XML resources to FastInfoset XML resources.
 * 
 * @goal xml2fastinfoset
 * @phase process-resources
 * @threadSafe
 */
public class XML2FastInfosetCompilerMojo extends AbstractMojo {
    private static final String[] EMPTY_STRING_ARRAY = {};
    private static final String[] DEFAULT_INCLUDES = {"**/*.xml"};

    /**
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * The resource directories containing the XML files to be compiled.
     * 
     * @parameter expression="${project.resources}"
     * @required
     * @readonly
     */
    private List resources;

    /**
     * A list of inclusion filters.
     * 
     * @parameter
     */
    private Set includes = new HashSet();

    /**
     * A list of exclusion filters.
     * 
     * @parameter
     */
    private Set excludes = new HashSet();

    /**
     * The directory for the results.
     * 
     * @parameter expression="${project.build.outputDirectory}"
     * @required
     */
    private File outputDirectory;
    
    /** @component */
    protected BuildContext buildContext;
        

    @SuppressWarnings("unchecked")
    public void execute() throws MojoExecutionException {

        for (Iterator it = resources.iterator(); it.hasNext();) {
            Resource resource = (Resource)it.next();
            String targetPath = resource.getTargetPath();

            File resourceDirectory = new File(resource.getDirectory());
            if (!resourceDirectory.isAbsolute()) {
                resourceDirectory = new File(project.getBasedir(), resourceDirectory.getPath());
            }

            if (!resourceDirectory.exists()) {
                getLog().debug("Resource directory does not exist: " + resourceDirectory);
                continue;
            }

            Scanner scanner = buildContext.newScanner(resourceDirectory);

            if (includes != null && !includes.isEmpty()) {
                scanner.setIncludes((String[])includes.toArray(EMPTY_STRING_ARRAY));
            } else {
                scanner.setIncludes(DEFAULT_INCLUDES);
            }

            if (excludes != null && !excludes.isEmpty()) {
                scanner.setExcludes((String[])excludes.toArray(EMPTY_STRING_ARRAY));
            }

            scanner.addDefaultExcludes();
            scanner.scan();

            List includedFiles = Arrays.asList(scanner.getIncludedFiles());

            getLog().debug("FastInfosetting " + includedFiles.size() + " resource"
                              + (includedFiles.size() > 1 ? "s" : "")
                              + (targetPath == null ? "" : " to " + targetPath));

            if (includedFiles.size() > 0) {
                // this part is required in case the user specified "../something"
                // as destination
                // see MNG-1345
                if (!outputDirectory.exists() && !outputDirectory.mkdirs()) {
                    throw new MojoExecutionException("Cannot create resource output directory: "
                                                     + outputDirectory);
                }
            }
            
            for (Iterator j = includedFiles.iterator(); j.hasNext();) {
                String name = (String)j.next();

                String destination = name.replaceFirst("\\.xml$", ".fixml");

                if (targetPath != null) {
                    destination = targetPath + "/" + name;
                }
                
                File source = new File(resourceDirectory, name);

                File destinationFile = new File(outputDirectory, destination);

                if (!destinationFile.getParentFile().exists()) {
                    destinationFile.getParentFile().mkdirs();
                }

                try {
                    compileFile(source, destinationFile);
                } catch (Exception e) {
                    throw new MojoExecutionException("Error copying resource " + source, e);
                }
                buildContext.refresh(destinationFile);
            }

        }
    }

    private void compileFile(File sourceFile, File destinationFile) throws ParserConfigurationException,
        SAXException, IOException {

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(sourceFile);
            fos = new FileOutputStream(destinationFile);
            dehydrate(fis, fos);
            fis.close();
            fos.close();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {
                // nothing.
            }
        }
    }

    private void dehydrate(InputStream input, OutputStream output) throws ParserConfigurationException,
        SAXException, IOException {
        // Create Fast Infoset SAX serializer
        SAXDocumentSerializer saxDocumentSerializer = new SAXDocumentSerializer();
        // Set the output stream
        saxDocumentSerializer.setOutputStream(output);

        // Instantiate JAXP SAX parser factory
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        saxParserFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
        saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        /*
         * Set parser to be namespace aware Very important to do otherwise
         * invalid FI documents will be created by the SAXDocumentSerializer
         */
        saxParserFactory.setNamespaceAware(true);
        // Instantiate the JAXP SAX parser
        SAXParser saxParser = saxParserFactory.newSAXParser();
        // Set the lexical handler
        saxParser.setProperty("http://xml.org/sax/properties/lexical-handler", saxDocumentSerializer);
        // Parse the XML document and convert to a fast infoset document
        saxParser.parse(input, saxDocumentSerializer);
    }

}
