/*
 * 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.myfaces.trinidadbuild.plugin.faces;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import java.net.URL;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.XIncludeFilter;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;


/**
 * @version $Id$
 * @requiresDependencyResolution compile
 * @goal generate-faces-config
 * @phase generate-resources
 */
public class GenerateFacesConfigMojo extends AbstractFacesMojo
{
  /**
   * Execute the Mojo.
   */
  public void execute() throws MojoExecutionException
  {
    try
    {
      // always add resources directory to project resource root
      addResourceRoot(project, targetDirectory.getCanonicalPath());

      File targetFile = new File(targetDirectory, targetPath);

      URL[] index = readIndex(project);

      if (!force && !isModifiedSince(index, targetFile.lastModified()))
      {
        getLog().info("Nothing to generate - " + targetPath + " is up to date");
      }
      else
      {
        List configURLs = getMasterConfigs(project);

        File configFile = new File(configDirectory, configPath);
        if (configFile.exists())
        {
          configURLs = new LinkedList(configURLs);
          // base config goes first
          configURLs.add(0, configFile.toURL());
        }

        if (!configURLs.isEmpty())
        {
          URL baseURL = GenerateFacesConfigMojo.class.getResource("resources/faces-config.xml");
          DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
          DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
          Document document = docBuilder.parse(baseURL.openStream());
          Element root = document.getDocumentElement();

          // embed each <xi:include> element
          for (Iterator i = configURLs.iterator(); i.hasNext(); )
          {
            URL url = (URL)i.next();
            Element include = document.createElementNS("http://www.w3.org/2001/XInclude",
                                                       "xi:include");
            include.setAttribute("href", url.toExternalForm());
            include.setAttribute("xpointer", "/faces-config/*");
            root.insertBefore(include, root.getFirstChild());
          }

          // Note: use a direct DOM->SAX reader
          //       rather than transforming to string
          TransformerFactory transFactory = TransformerFactory.newInstance();
          Transformer identity = transFactory.newTransformer();
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          identity.transform(new DOMSource(document), new StreamResult(out));

          InputStream mergedStream = new ByteArrayInputStream(out.toByteArray());
          // expand all the xi:include elements
          SAXParserFactory saxFactory = SAXParserFactory.newInstance();
          saxFactory.setNamespaceAware(true);
          saxFactory.setValidating(false);
          SAXParser saxParser = saxFactory.newSAXParser();
          XMLReader mergedReader = saxParser.getXMLReader();
          mergedReader = new XIncludeFilter(mergedReader, baseURL);
          mergedReader.setEntityResolver(new EntityResolver()
            {
              public InputSource resolveEntity(
                String publicId,
                String systemId)
              {
                return new InputSource(new ByteArrayInputStream(new byte[0]));
              }
            });
          InputSource mergedInput = new InputSource(mergedStream);
          Source mergedSource = new SAXSource(mergedReader, mergedInput);

          // Transform the combined faces-config.xml file to resolve
          // component-supertype, inject the DTD and ensure that
          // metadata is represented compatibly with JSF 1.1 syntax.
          targetFile.delete();
          targetFile.getParentFile().mkdirs();

          File tmpFile = null;
          OutputStream resultStream;
          if (transformStylesheet != null)
          {
            tmpFile = File.createTempFile("generate-faces-config", null);
            resultStream = new FileOutputStream(tmpFile);
          }
          else
          {
            resultStream = new FileOutputStream(targetFile);
          }

          Result mergedResult = new StreamResult(resultStream);

          URL xslURL;
          boolean isJsf2 = false;
          JsfVersion usedVersion = JsfVersion.getVersion(jsfVersion);
          if (usedVersion == JsfVersion.JSF_1_2)
          {
            xslURL = getClass().getResource("resources/transform12.xsl");
          }
          else if (usedVersion == JsfVersion.JSF_2_0)
          {
            xslURL = getClass().getResource("resources/transform20.xsl");
            isJsf2 = true;
          }
          else if (usedVersion == JsfVersion.JSF_2_1)
          {
            xslURL = getClass().getResource("resources/transform21.xsl");
            isJsf2 = true;
          }
          else
          {
            xslURL = getClass().getResource("resources/transform.xsl");
          }

          InputStream xsl = xslURL.openStream();
          StreamSource xslSource = new StreamSource(xsl);
          //this resolver is to make sure imports of other stylesheets within the classpath get loaded
          transFactory.setURIResolver(new JarResourceResolver());
          Transformer transformer = transFactory.newTransformer(xslSource);
          transformer.setParameter("packageContains", packageContains);
          transformer.setParameter("typePrefix", typePrefix);
          transformer.setParameter("removeRenderers",
                                   removeRenderers ? "true" : "false");
          transformer.setParameter("converterPackageContains", getParameter(converterPackageContains, packageContains));
          transformer.setParameter("validatorPackageContains", getParameter(validatorPackageContains, packageContains));
          
          if (isJsf2 && metadataComplete)
          {
            transformer.setParameter("metadataComplete", "true");
          }

          transformer.transform(mergedSource, mergedResult);
          resultStream.close();

          // OK, if there's a transformSylesheet, we've written
          // the output to a temporary file, now transform it again.
          // =-=FIXME AdamWiner:  no, this is not the smartest and
          // fastest way to do it.  But after finding out
          // that XMLFilter apparently doesn't support XSL parameters,
          // and running into a bizarre "illegal processing instruction:
          // saxon:warning" error message when using chained handlers, I got
          // tired of trying to be smart.  This is good enough.
          if (transformStylesheet != null)
          {
            StreamSource tmpSource = new StreamSource(tmpFile);
            StreamSource transformSource = new StreamSource(
                new File(configDirectory, transformStylesheet));
            Transformer finalTransform =
              transFactory.newTransformer(transformSource);
            FileOutputStream finalOut = new FileOutputStream(targetFile);
            Result finalResult =
              new StreamResult(finalOut);

            finalTransform.transform(tmpSource, finalResult);
            finalOut.close();
            tmpFile.delete();
          }


          targetFile.setReadOnly();

          getLog().info("Generated " + targetPath);
        }
      }
    }
    catch (SAXException e)
    {
      throw new MojoExecutionException("Error during generation", e);
    }
    catch (TransformerException e)
    {
      throw new MojoExecutionException("Error during generation", e);
    }
    catch (ParserConfigurationException e)
    {
      throw new MojoExecutionException("Error during generation", e);
    }
    catch (IOException e)
    {
      throw new MojoExecutionException("Error during generation", e);
    }
  }

  private String getParameter(String paramName, String defaultValue)
  {
    String param;

    if (paramName.length() > 0)
    {
       param = paramName;
    }
    else
    {
        param = defaultValue;
    }
    return param;
  }

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

  /**
   * @parameter expression="src/main/conf"
   * @required
   */
  private File configDirectory;

  /**
   * @parameter
   */
  private String configPath = "META-INF/faces-config-base.xml";

  /**
   * @parameter
   */
  private String packageContains = "";

  /**
   * @parameter
   */
  private String converterPackageContains = "";

  /**
   * @parameter
   */
  private String validatorPackageContains = "";


  /**
   * @parameter expression="${project.build.directory}/maven-faces-plugin/main/resources"
   * @required
   */
  private File targetDirectory;

  /**
   * @parameter
   */
  private String targetPath = "META-INF/faces-config.xml";

  /**
   * @parameter
   */
  private boolean force;

  /**
   * @parameter
   */
  private String typePrefix = "";

  /**
   * Name of an XSLT stylesheet in src/main/conf that will be applied
   * as the final step.  This can be used to implement any final fixup
   * of the output.
   * @parameter
   */
  private String transformStylesheet;

  /**
   * @parameter
   */
  private boolean removeRenderers;

  /**
   * @parameter
   */
  private String jsfVersion;
  
  /**
   * @parameter
   */
  private boolean metadataComplete;
}
