/*
 *  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.buildtools.maven2.plugin.xrts;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

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

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

import org.codehaus.plexus.util.DirectoryScanner;

import org.xml.sax.InputSource;

/**
 * @version $Id$
 * @phase generate-resources
 * @description Goal which generates the XRTS Bundles
 */
abstract public class AbstractGenerateSourcesMojo extends AbstractMojo
{
  /**
   * Execute the Mojo.
   */
  public void execute() throws MojoExecutionException
  {
    try
    {
      generateBundles();
    }
    catch (IOException e)
    {
      throw new MojoExecutionException(e.getMessage());
    }
  }

  abstract protected String getTargetType();

  abstract protected String[] getDefaultLocales();

  abstract protected String[] getExcludes();

  abstract protected File getSourceDirectory();

  abstract protected File getTargetDirectory();

  abstract protected void addCompileSourceRoot() throws IOException;

  private void generateBundles() throws IOException, MojoExecutionException
  {
    File sourceDirectory = getSourceDirectory();
    if (sourceDirectory.exists())
    {
      // Include generated sources in compilation
      addCompileSourceRoot();

      // Scan for .xrts sources
      DirectoryScanner scanner = new DirectoryScanner();
      scanner.setBasedir(sourceDirectory);
      scanner.addDefaultExcludes();
      String[] excludes = getExcludes();
      scanner.setExcludes(excludes);
      scanner.setIncludes(new String[] { "**/*.xrts" });
      scanner.scan();

      String[] xrtsFiles = scanner.getIncludedFiles();
      if (xrtsFiles.length > 0)
      {
        RTSWriter writer = getRTSWriter();
        Map params = new HashMap();

        List dirtyXRTS = new LinkedList(Arrays.asList(xrtsFiles));
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(false);

        for (Iterator i=dirtyXRTS.iterator(); i.hasNext();)
        {
          String xrtsFile = (String)i.next();
          File targetFile = getTargetFile(xrtsFile);
          if (targetFile.exists())
          {
            File sourceFile = getSourceFile(xrtsFile);
            if (targetFile.lastModified() >= sourceFile.lastModified())
            {
              i.remove();
            }
          }
        }

        if (dirtyXRTS.isEmpty())
        {
          getLog().info("Nothing to generate - all XRTS bundles are up to date");
        }
        else
        {
          getLog().info("Generating " + dirtyXRTS.size() + " XRTS bundles to " + getTargetDirectory());

          for (Iterator i=dirtyXRTS.iterator(); i.hasNext();)
          {
            String xrtsFile = (String)i.next();
            File sourceFile = getSourceFile(xrtsFile);
            File targetFile = getTargetFile(xrtsFile);
            String baseName = getBasename(xrtsFile);

            params.put("outFile", targetFile);
            params.put("outName", baseName);
            params.put("srcName", baseName);
            params.put("quietMode", Boolean.TRUE);
            params.put("defaultLocales", getDefaultLocales());
            InputSource source = new InputSource(new FileInputStream(sourceFile));
            // setup relative systemId resolution for local rts.dtd files.
            source.setSystemId(sourceFile.getParentFile().toURL().toString());

            try
            {
              if (targetFile.exists())
              {
                targetFile.delete();
              }

              SAXParser parser = factory.newSAXParser();
              targetFile.getParentFile().mkdirs();
              XRTSGenerator.generate(parser, source, writer, params);
              targetFile.setReadOnly();
            }
            catch (Throwable t)
            {
              throw new MojoExecutionException(t.getMessage());
            }
          }
        }
      }
    }
  }

  private RTSWriter getRTSWriter() throws IOException, MojoExecutionException
  {
    String implClassName;

    String targetType = getTargetType();
    if (targetType.startsWith("class:"))
    {
      implClassName = targetType.substring("class:".length());
    }
    else
    {
      if ("list".equals(targetType))
      {
        return new ListRTSWriter();
      }
      throw new MojoExecutionException("Unknown bundle type: " + targetType);
    }

    try
    {
      Class implClass = Class.forName(implClassName);
      return (RTSWriter)implClass.newInstance();
    }
    catch (InstantiationException e)
    {
      e.printStackTrace();
      throw new MojoExecutionException(e.getMessage());
    }
    catch (ClassNotFoundException e)
    {
      e.printStackTrace();
      throw new MojoExecutionException(e.getMessage());
    }
    catch (IllegalAccessException e)
    {
      e.printStackTrace();
      throw new MojoExecutionException(e.getMessage());
    }
  }

  private File getSourceFile(String xrtsFilename)
  {
    return new File(getSourceDirectory(), xrtsFilename);
  }

  private String getBasename(String sourcePath)
  {
    int start = sourcePath.lastIndexOf(File.separatorChar) + 1;
    return sourcePath.substring(start, sourcePath.length() - ".xrts".length());
  }

  private File getTargetFile(String sourcePath)
  {
    String basename = sourcePath.substring(0, sourcePath.length() - ".xrts".length());
    String targetPath = basename + ".java";
    return new File(getTargetDirectory(), targetPath);
  }
}
