/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed 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 com.google.gwt.user.tools;

import com.google.gwt.dev.About;
import com.google.gwt.dev.ArgProcessorBase;
import com.google.gwt.dev.Compiler;
import com.google.gwt.dev.DevMode;
import com.google.gwt.dev.GwtVersion;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.collect.HashSet;
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
import com.google.gwt.user.tools.util.CreatorUtilities;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerFlag;
import com.google.gwt.util.tools.ArgHandlerOutDir;
import com.google.gwt.util.tools.ArgHandlerString;
import com.google.gwt.util.tools.Utility;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Creates a GWT application skeleton.
 */
public final class WebAppCreator {

  class ArgProcessor extends ArgProcessorBase {

    private final class ArgHandlerOutDirExtension extends ArgHandlerOutDir {
      @Override
      public void setDir(File dir) {
        outDir = dir;
      }
    }

    public ArgProcessor() {
      registerHandler(new ArgHandlerOverwriteExtension());
      registerHandler(new ArgHandlerIgnoreExtension());
      registerHandler(new ArgHandlerTemplates());
      registerHandler(new ArgHandlerModuleName());
      registerHandler(new ArgHandlerOutDirExtension());
      registerHandler(new ArgHandlerNoEclipse());
      registerHandler(new ArgHandlerOnlyEclipse());
      registerHandler(new ArgHandlerJUnitPath());
      registerHandler(new ArgHandlerMaven());
      registerHandler(new ArgHandlerNoAnt());
    }

    @Override
    protected String getName() {
      return WebAppCreator.class.getName();
    }
  }

  private final class ArgHandlerIgnoreExtension extends ArgHandlerIgnore {
    @Override
    public boolean setFlag() {
      if (overwrite) {
        System.err.println("-ignore cannot be used with -overwrite");
        return false;
      }
      ignore = true;
      return true;
    }
  }

  private final class ArgHandlerJUnitPath extends ArgHandlerString {

    @Override
    public String[] getDefaultArgs() {
      return null;
    }

    @Override
    public String getPurpose() {
      return "Specifies the path to your junit.jar (optional)";
    }

    @Override
    public String getTag() {
      return "-junit";
    }

    @Override
    public String[] getTagArgs() {
      return new String[] {"pathToJUnitJar"};
    }

    @Override
    public boolean isRequired() {
      return false;
    }

    @Override
    public boolean setString(String str) {
      File f = new File(str);
      if (!f.exists() || !f.isFile()) {
        System.err.println("File not found: " + str);
        return false;
      }
      junitPath = str;
      return true;
    }
  }

  private final class ArgHandlerMaven extends ArgHandlerFlag {
    @Override
    public String getPurpose() {
      return "Deprecated. Create a maven2 project structure and pom file (default disabled). "
          + "Equivalent to specifying 'maven' in the list of templates.";
    }

    @Override
    public String getTag() {
      return "-maven";
    }

    @Override
    public boolean setFlag() {
      if (onlyEclipse) {
        System.err.println("-maven and -XonlyEclipse cannot be used at the same time.");
        return false;
      }
      if (!templates.contains("maven")) {
        templates.add("maven");
      }
      return true;
    }
  }

  private final class ArgHandlerModuleName extends ArgHandlerExtra {
    @Override
    public boolean addExtraArg(String arg) {
      if (moduleName != null) {
        System.err.println("Too many arguments.");
        return false;
      }

      if (!CreatorUtilities.isValidModuleName(arg)) {
        System.err.println("'"
            + arg
            + "' does not appear to be a valid fully-qualified Java class name.");
        return false;
      }

      moduleName = arg;
      return true;
    }

    @Override
    public String getPurpose() {
      return "The name of the module to create (e.g. com.example.myapp.MyApp)";
    }

    @Override
    public String[] getTagArgs() {
      return new String[] {"moduleName"};
    }

    @Override
    public boolean isRequired() {
      return true;
    }
  }

  private final class ArgHandlerNoAnt extends ArgHandlerFlag {
    @Override
    public String getPurpose() {
      return "Deprecated. Do not create an ant configuration file. "
          + "Equivalent to not specifying 'ant' in the list of templates.";
    }

    @Override
    public String getTag() {
      return "-noant";
    }

    @Override
    public boolean setFlag() {
      argProcessingToDos.add(new Procrastinator() {
        @Override
        public void stopProcratinating() {
          if (templates.contains("maven")) {
            System.err.println("-maven and -noant are redundant. Continuing.");
          }
          if (templates.contains("ant")) {
            System.err.println("Removing ant template from generated output.");
            templates.remove("ant");
          }
        }
      });
      return true;
    }
  }

  private final class ArgHandlerNoEclipse extends ArgHandlerFlag {
    @Override
    public String getPurpose() {
      return "Deprecated. Do not generate eclipse files. "
          + "Equivalent to not specifying 'eclipse' in the list of templates";
    }

    @Override
    public String getTag() {
      return "-XnoEclipse";
    }

    @Override
    public boolean isUndocumented() {
      return true;
    }

    @Override
    public boolean setFlag() {
      if (onlyEclipse) {
        System.err.println("-XonlyEclipse and -XnoEclipse cannot be used at the same time.");
        return false;
      }
      if (!templates.contains("maven")) {
        System.err.println("-maven and -XnoEclipse are redundant. Continuing.");
      }
      noEclipse = true;
      argProcessingToDos.add(new Procrastinator() {
        @Override
        public void stopProcratinating() {
          if (templates.contains("eclipse")) {
            System.err.println("Removing eclipse template from generated output.");
            templates.remove("eclipse");
          }
        }
      });
      return true;
    }
  }

  private final class ArgHandlerOnlyEclipse extends ArgHandlerFlag {
    @Override
    public String getPurpose() {
      return "Deprecated. Generate only eclipse files. "
          + "Equivalent to only specifying 'eclipse' in the list of templates.";
    }

    @Override
    public String getTag() {
      return "-XonlyEclipse";
    }

    @Override
    public boolean isUndocumented() {
      return true;
    }

    @Override
    public boolean setFlag() {
      if (noEclipse) {
        System.err.println("-XonlyEclipse and -XnoEclipse cannot be used at the same time.");
        return false;
      }
      if (templates.contains("maven")) {
        System.err.println("-maven and -XonlyEclipse cannot be used at the same time.");
        return false;
      }
      onlyEclipse = true;
      argProcessingToDos.add(new Procrastinator() {
        @Override
        public void stopProcratinating() {
          System.err.println("Removing all templates but 'eclipse' from generated output.");
          templates.clear();
          templates.add("eclipse");
        }
      });
      return true;
    }
  }

  private final class ArgHandlerOverwriteExtension extends ArgHandlerOverwrite {
    @Override
    public boolean setFlag() {
      if (ignore) {
        System.err.println("-overwrite cannot be used with -ignore");
        return false;
      }
      overwrite = true;
      return true;
    }
  }

  private final class ArgHandlerTemplates extends ArgHandlerString {

    @Override
    public String[] getDefaultArgs() {
      return new String[] {getTag(), "sample, ant, eclipse, readme"};
    }

    @Override
    public String getPurpose() {
      return "Specifies the template(s) to use (comma separeted)."
          + " Defaults to 'sample,ant,eclipse,readme'";
    }

    @Override
    public String getTag() {
      return "-templates";
    }

    @Override
    public String[] getTagArgs() {
      return new String[] {"template1,template2,..."};
    }

    @Override
    public boolean isRequired() {
      return false;
    }

    @Override
    public boolean setString(String str) {
      String[] templateList = str.split(", *");
      for (String template : templateList) {
        URL url = getTemplateRoot(template);
        if (url == null) {
          System.err.println("Template not found: " + template);
          return false;
        }
        templates.add(template);
      }
      return true;
    }
  }

  private static final class FileCreator {
    private final File destDir;

    private final String destName;
    private final boolean isBinary;
    private final String sourceName;
    public FileCreator(File destDir, String destName, String sourceName, boolean isBinary) {
      this.destDir = destDir;
      this.sourceName = sourceName;
      this.destName = destName;
      this.isBinary = isBinary;
    }

    @Override
    public String toString() {
      return "FileCreator [destDir=" + destDir + ", destName=" + destName
          + ", sourceName=" + sourceName + ", isBinary=" + isBinary + "]";
    }
  }

  private abstract static class Procrastinator {
    public abstract void stopProcratinating();
  }

  public static void main(String[] args) {
    System.exit(doMain(args) ? 0 : 1);
  }

  protected static boolean doMain(String... args) {
    WebAppCreator creator = new WebAppCreator();
    ArgProcessor argProcessor = creator.new ArgProcessor();
    if (argProcessor.processArgs(args)) {
      return creator.run();
    }
    return false;
  }

  private static String getTemplateBasePath(String template) {
    return "/" + WebAppCreator.class.getPackage().getName().replace('.', '/') + "/templates/" 
        + template + "/";
  }

  private static URL getTemplateRoot(String template) {
    return WebAppCreator.class.getResource("templates/" + template);
  }

  private static String replaceFileName(Map<String, String> replacements, String name) {
    String replacedContents = name;
    Set<Entry<String, String>> entries = replacements.entrySet();
    for (Iterator<Entry<String, String>> iter = entries.iterator(); iter.hasNext();) {
      Entry<String, String> entry = iter.next();
      String replaceThis = entry.getKey();
      replaceThis = replaceThis.replaceAll("@(.*)", "_$1_");
      String withThis = entry.getValue();
      withThis = withThis.replaceAll("\\\\", "\\\\\\\\");
      withThis = withThis.replaceAll("\\$", "\\\\\\$");
      replacedContents = replacedContents.replaceAll(replaceThis, withThis);
    }
    return replacedContents;
  }
  private ArrayList<Procrastinator> argProcessingToDos = new ArrayList<Procrastinator>();
  private boolean ignore = false;
  private String junitPath = null;
  private String moduleName;
  private boolean noEclipse;
  private boolean onlyEclipse;
  private File outDir;
  private boolean overwrite = false;

  private HashSet<String> templates = new HashSet<String>();

  public List<FileCreator> getFiles(Map<String, String> replacements)
      throws IOException, WebAppCreatorException {
    List<FileCreator> files = new ArrayList<FileCreator>();

    Utility.getDirectory(outDir.getPath(), true);

    for (String template : templates) {
      URL templateUrl = getTemplateRoot(template);
      if ("jar".equals(templateUrl.getProtocol())) {
        files.addAll(getTemplateFilesFromZip(replacements, templateUrl, outDir));
      } else if ("file".equals(templateUrl.getProtocol())) {
        File templateRoot = new File(templateUrl.getPath());
        files.addAll(getTemplateFiles(replacements, templateRoot, outDir,
            getTemplateBasePath(template)));
      } else {
        throw new WebAppCreatorException("Cannot handle template '" + template + "' protocol: " 
            + templateUrl.getProtocol());
      }
    }
    
    return files;
  }

  public Map<String, String> getReplacements(String installPath, String theModuleName) {
    // GWT libraries
    String gwtUserPath = installPath + '/' + "gwt-user.jar";
    String gwtDevPath = installPath + '/' + "gwt-dev.jar";
    String gwtValidationPath = installPath + '/' + "validation-api-1.0.0.GA.jar";
    String gwtValidationSourcesPath = installPath + '/' + "validation-api-1.0.0.GA-sources.jar";

    // Public builds generate a DTD reference.
    String gwtModuleDtd = "";
    GwtVersion gwtVersion = About.getGwtVersionObject();
    if (gwtVersion.isNoNagVersion()) {
      gwtModuleDtd = "\n<!DOCTYPE module PUBLIC \"-//Google Inc.//DTD Google Web Toolkit "
          + About.getGwtVersionNum()
          + "//EN\" \"http://google-web-toolkit.googlecode.com/svn/tags/"
          + About.getGwtVersionNum()
          + "/distro-source/core/src/gwt-module.dtd\">";
    }

    // Compute module package and name.
    int pos = theModuleName.lastIndexOf('.');
    String modulePackageName = theModuleName.substring(0, pos);
    String moduleShortName = theModuleName.substring(pos + 1);

    // Create a map of replacements
    Map<String, String> replacements = new HashMap<String, String>();

    // Compute module name and directories
    String srcFolder = templates.contains("maven") ? "src/main/java" : "src";
    String testFolder = templates.contains("maven") ? "src/test/java" : "test";
    String warFolder = templates.contains("maven") ? "src/main/webapp" : "war";

    {
      // pro-actively let ant user know that this script can also create tests.
      if (junitPath == null) {
        System.err.println("Not creating tests because -junit argument was not specified.\n");
      }

      String testTargetsBegin = "";
      String testTargetsEnd = "";
      String junitJarPath = junitPath;
      String eclipseTestDir = "";
      if (junitPath != null) {
        eclipseTestDir = "\n   <classpathentry kind=\"src\" path=\""
            + testFolder + "\"/>";
      }
      if (junitPath == null) {
        testTargetsBegin = "\n<!--"
            + "\n"
            + "Test targets suppressed because -junit argument was not specified when running"
            + " webAppCreator.\n";
        testTargetsEnd = "-->\n";
        junitJarPath = "path_to_the_junit_jar";
      }
      replacements.put("@testTargetsBegin", testTargetsBegin);
      replacements.put("@testTargetsEnd", testTargetsEnd);
      replacements.put("@junitJar", junitJarPath);
      replacements.put("@eclipseTestDir", eclipseTestDir);
    }

    replacements.put("@srcFolder", srcFolder);
    replacements.put("@testFolder", testFolder);
    replacements.put("@warFolder", warFolder);

    replacements.put("@moduleShortName", moduleShortName);
    replacements.put("@modulePackageName", modulePackageName);
    replacements.put("@moduleFolder", modulePackageName.replace('.', '/'));
    replacements.put("@moduleName", theModuleName);
    replacements.put("@clientPackage", modulePackageName + ".client");
    replacements.put("@serverPackage", modulePackageName + ".server");
    replacements.put("@sharedPackage", modulePackageName + ".shared");
    replacements.put("@gwtSdk", installPath);
    replacements.put("@gwtUserPath", gwtUserPath);
    replacements.put("@gwtDevPath", gwtDevPath);
    replacements.put("@gwtValidationPath", gwtValidationPath);
    replacements.put("@gwtValidationSourcesPath", gwtValidationSourcesPath);
    replacements.put("@gwtVersion", About.getGwtVersionNum());
    replacements.put("@gwtModuleDtd", gwtModuleDtd);
    replacements.put("@shellClass", DevMode.class.getName());
    replacements.put("@compileClass", Compiler.class.getName());
    replacements.put("@startupUrl", moduleShortName + ".html");
    replacements.put("@renameTo", moduleShortName.toLowerCase());
    replacements.put("@moduleNameJUnit", theModuleName + "JUnit");

    // Add command to copy gwt-servlet-deps.jar into libs, unless this is a
    // maven project. Maven projects should include libs as maven dependencies.
    String copyServletDeps = "";
    copyServletDeps = "<copy todir=\"" + warFolder + "/WEB-INF/lib\" "
        + "file=\"${gwt.sdk}/gwt-servlet-deps.jar\" />";
    replacements.put("@copyServletDeps", copyServletDeps);

    // Collect the list of server libs to include on the eclipse classpath.
    File libDirectory = new File(outDir + warFolder + "WEB-INF/lib");
    StringBuilder serverLibs = new StringBuilder();
    if (libDirectory.exists()) {
      for (File file : libDirectory.listFiles()) {
        if (file.getName().toLowerCase().endsWith(".jar")) {
          serverLibs.append("   <classpathentry kind=\"lib\" path=\"war/WEB-INF/lib/");
          serverLibs.append(file.getName());
          serverLibs.append("\"/>\n");
        }
      }
    }
    replacements.put("@serverClasspathLibs", serverLibs.toString());

    String antEclipseRule = "";
    if (!templates.contains("eclipse")) {
      /*
       * Generate a rule into the build file that allows for the generation of
       * an eclipse project later on. This is primarily for distro samples. This
       * is a quick and dirty way to inject a build rule, but it works.
       */
      antEclipseRule = "\n\n"
          + "  <target name=\"eclipse.generate\" depends=\"libs\" description"
          + "=\"Generate eclipse project\">\n"
          + "    <java failonerror=\"true\" fork=\"true\" classname=\""
          + this.getClass().getName() + "\">\n" + "      <classpath>\n"
          + "        <path refid=\"project.class.path\"/>\n"
          + "      </classpath>\n" + "      <arg value=\"-XonlyEclipse\"/>\n"
          + "      <arg value=\"-ignore\"/>\n" + "      <arg value=\""
          + theModuleName + "\"/>\n" + "    </java>\n" + "  </target>";
    } else {
      antEclipseRule = "";
    }
    replacements.put("@antEclipseRule", antEclipseRule);
    return replacements;
  }

  /**
   * Create the sample app.
   * 
   * @throws IOException if any disk write fails
   * @throws WebAppCreatorException if any tag expansion of template processing fails
   * @deprecated as of GWT 2.1, replaced by {@link #doRun(String)}
   */
  @Deprecated
  protected void doRun() throws IOException, WebAppCreatorException {
    doRun(Utility.getInstallPath());
  }

  /**
   * Create the sample app.
   * 
   * @param installPath directory containing GWT libraries
   * @throws IOException if any disk write fails
   * @throws WebAppCreatorException  if any tag expansion of template processing fails
   */
  protected void doRun(String installPath) throws IOException, WebAppCreatorException {
    for (Procrastinator toDo : argProcessingToDos) {
      toDo.stopProcratinating();
    }

    // Maven projects do not need Ant nor Eclipse files
    if (templates.contains("maven")) {
      junitPath = "junit-provided-by-maven";

      if (templates.contains("eclipse")) {
        System.err.println("'maven' template is being generated removing 'eclipse'"
            + " template from generated output.");
        templates.remove("eclipse");            
      }
      if (templates.contains("ant")) {
        System.err.println("'maven' template is being generated removing 'ant'"
            + " template from generated output.");
        templates.remove("ant");
      }
    }

    // Eagerly look for test templates
    if (junitPath != null) {
      ArrayList<String> testTemplates = new ArrayList<String>();
      for (String template : templates) {
        String testTemplateName = "_" + template + "-test";
        if (getTemplateRoot(testTemplateName) != null) {
          testTemplates.add(testTemplateName);
        }
      }
      templates.addAll(testTemplates);
    }

    System.out.println("Generating from templates: " + templates);

    // Generate string replacements 
    Map<String, String> replacements = getReplacements(installPath, moduleName);

    // Create a list with the files to create
    List<FileCreator> files = getFiles(replacements);

    // copy source files, replacing the content as needed
    for (FileCreator fileCreator : files) {
      URL url = WebAppCreator.class.getResource(fileCreator.sourceName);
      if (url == null) {
        throw new WebAppCreatorException("Could not find " + fileCreator.sourceName);
      }
      File file = Utility.createNormalFile(fileCreator.destDir,
          fileCreator.destName, overwrite, ignore);
      if (file == null) {
        continue;
      }
      if (fileCreator.isBinary) {
        byte[] data = Util.readURLAsBytes(url);
        Utility.writeTemplateBinaryFile(file, data);
      } else {
        String data = Util.readURLAsString(url);
        Utility.writeTemplateFile(file, data, replacements);
      }
    }
  }

  protected boolean run() {
    try {
      doRun(Utility.getInstallPath());
      return true;
    } catch (IOException e) {
      System.err.println(e.getClass().getName() + ": " + e.getMessage());
      return false;
    } catch (WebAppCreatorException e) {
      System.err.println(e.getClass().getName() + ": " + e.getMessage());
      return false;
    }
  }

  private Collection<? extends FileCreator> getTemplateFiles(
      Map<String, String> replacements, File srcDirectory, File destDirectory,
      String templateClassRoot) throws IOException {
    List<FileCreator> files = new ArrayList<FileCreator>();
    
    File[] filesInDir = srcDirectory.listFiles();

    for (File srcFile : filesInDir) {
      String replacedName = replaceFileName(replacements, srcFile.getName());
      
      if (srcFile.isDirectory()) {
        File newDirectory = Utility.getDirectory(destDirectory, replacedName, true);
        files.addAll(getTemplateFiles(replacements, srcFile, newDirectory, templateClassRoot
            + srcFile.getName() + "/"));
      } else if (srcFile.getName().endsWith("src")) {
        String srcFilename = templateClassRoot + srcFile.getName();
        String destName = replacedName.substring(0, replacedName.length() - 3);
        files.add(new FileCreator(destDirectory, destName, srcFilename, false));
      } else if (srcFile.getName().endsWith("bin")) {
        String srcFilename = templateClassRoot + srcFile.getName();
        String destName = replacedName.substring(0, replacedName.length() - 3);
        files.add(new FileCreator(destDirectory, destName, srcFilename, true));
      } // else ... ignore everything not a directory, "*src" nor "*bin"
    }
    
    return files;
  }

  private Collection<? extends FileCreator> getTemplateFilesFromZip(
      Map<String, String> replacements, URL zipUrl, File destDirectory)
      throws WebAppCreatorException, IOException {
    String zipPath = zipUrl.getFile();
    int separator = zipPath.indexOf('!');

    if (separator == -1) {
      throw new WebAppCreatorException("Error opening template zip file. '!' not found in "
          + zipUrl);
    }

    String zipFilename = zipPath.substring(0, separator);
    String templateDirName = zipPath.substring(separator + 2);
    ZipFile zipFile;

    try {
      zipFile = new ZipFile(new File(new URI(zipFilename)));
    } catch (URISyntaxException e) {
      throw new WebAppCreatorException("Could not open Zip file. Malformed URI", e);
    }

    Enumeration<? extends ZipEntry> allZipEntries = zipFile.entries();

    ArrayList<FileCreator> templateEntries = new ArrayList<FileCreator>(); 

    while (allZipEntries.hasMoreElements()) {
      ZipEntry entry = allZipEntries.nextElement();
      String fullName = entry.getName();
      if (fullName.startsWith(templateDirName + "/")) {
        String relativeName = fullName.substring(templateDirName.length());
        String replacedName = replaceFileName(replacements, relativeName);
        if (entry.isDirectory()) {
          Utility.getDirectory(destDirectory, replacedName, true);
        } else if (fullName.endsWith("src")) {
          // remove the src suffix 
          String destName = replacedName.substring(0, replacedName.length() - 3);
          templateEntries.add(new FileCreator(destDirectory, destName, "/" + fullName, false));
        } else if (fullName.endsWith("bin")) {
          String destName = replacedName.substring(0, replacedName.length() - 3);
          templateEntries.add(new FileCreator(destDirectory, destName, "/" + fullName, true));
        }
      } // else ... ignore everything not a directory, "*src" nor "*bin"
    }

    return templateEntries;
  }

}
