/*
 * Copyright 2011 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.dev.codeserver;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.ArgProcessorBase;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.jjs.JsOutputOption;
import com.google.gwt.dev.util.arg.ArgHandlerBindAddress;
import com.google.gwt.dev.util.arg.ArgHandlerClosureFormattedOutput;
import com.google.gwt.dev.util.arg.ArgHandlerFilterJsInteropExports;
import com.google.gwt.dev.util.arg.ArgHandlerGenerateJsInteropExports;
import com.google.gwt.dev.util.arg.ArgHandlerIncrementalCompile;
import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
import com.google.gwt.dev.util.arg.ArgHandlerMethodNameDisplayMode;
import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
import com.google.gwt.dev.util.arg.ArgHandlerSetProperties;
import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
import com.google.gwt.dev.util.arg.OptionBindAddress;
import com.google.gwt.dev.util.arg.OptionClosureFormattedOutput;
import com.google.gwt.dev.util.arg.OptionGenerateJsInteropExports;
import com.google.gwt.dev.util.arg.OptionIncrementalCompile;
import com.google.gwt.dev.util.arg.OptionLogLevel;
import com.google.gwt.dev.util.arg.OptionMethodNameDisplayMode;
import com.google.gwt.dev.util.arg.OptionScriptStyle;
import com.google.gwt.dev.util.arg.OptionSetProperties;
import com.google.gwt.dev.util.arg.OptionSourceLevel;
import com.google.gwt.dev.util.arg.SourceLevel;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.LinkedListMultimap;
import com.google.gwt.thirdparty.guava.common.collect.ListMultimap;
import com.google.gwt.util.regexfilter.WhitelistRegexFilter;
import com.google.gwt.util.tools.ArgHandler;
import com.google.gwt.util.tools.ArgHandlerDir;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerFlag;
import com.google.gwt.util.tools.ArgHandlerInt;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * Defines the command-line options for the {@link CodeServer CodeServer's} main() method.
 *
 * <p>These flags are EXPERIMENTAL and subject to change.</p>
 */
public class Options {
  private ImmutableList<String> args;
  private Set<String> tags = new LinkedHashSet<String>();

  private boolean incremental = true;
  private boolean noPrecompile = false;
  private boolean isCompileTest = false;
  private File workDir;
  private File launcherDir;
  private final List<String> moduleNames = new ArrayList<String>();
  private boolean allowMissingSourceDir = false;
  private final List<File> sourcePath = new ArrayList<File>();
  private String bindAddress = ArgHandlerBindAddress.DEFAULT_BIND_ADDRESS;
  private String preferredHost = ArgHandlerBindAddress.DEFAULT_BIND_ADDRESS;
  private int port = 9876;

  private RecompileListener recompileListener = RecompileListener.NONE;
  private JobChangeListener jobChangeListener = JobChangeListener.NONE;

  private TreeLogger.Type logLevel = TreeLogger.Type.INFO;
  // Use the same default as the GWT compiler.
  private SourceLevel sourceLevel = SourceLevel.DEFAULT_SOURCE_LEVEL;
  private boolean failOnError = false;
  private int compileTestRecompiles = 0;
  private boolean generateJsInteropExports = false;
  private WhitelistRegexFilter jsInteropExportFilter = new WhitelistRegexFilter();
  private OptionMethodNameDisplayMode.Mode methodNameDisplayMode =
      OptionMethodNameDisplayMode.Mode.NONE;
  private boolean closureFormattedOutput = false;
  // Incremental superdevmod has different defaults than devmode and regular superdevmode; we use
  // null here means not set by the user (and the right default is computed by getOutput().
  private JsOutputOption output = null;

  private final ListMultimap<String, String> properties = LinkedListMultimap.create();

  /**
   * Sets each option to the appropriate value, based on command-line arguments.
   * If there is an error, prints error messages and/or usage to System.err.
   * @return true if the arguments were parsed successfully.
   */
  public boolean parseArgs(String[] args) {
    if (this.args != null) {
      throw new IllegalStateException("parseArgs may only be called once");
    }
    this.args = ImmutableList.copyOf(Arrays.asList(args));

    boolean ok = new ArgProcessor().processArgs(args);
    if (!ok) {
      return false;
    }

    if (isCompileTest && noPrecompile) {
      System.err.println("Usage: -noprecompile and -compiletest are incompatible");
      return false;
    }

    if (moduleNames.isEmpty()) {
      System.err.println("Usage: at least one module must be supplied");
      return false;
    }

    if (incremental && !noPrecompile) {
      System.out.println("Turning off precompile in incremental mode.");
      noPrecompile = true;
    }

    // Set some tags automatically for migration tracking.
    if (isIncrementalCompileEnabled()) {
      addTags("incremental_on");
    } else {
      addTags("incremental_off");
    }

    if (getNoPrecompile()) {
      addTags("precompile_off");
    } else {
      addTags("precompile_on");
    }

    return true;
  }

  /**
   * Adds some user-defined tags that will be passed through to {@link JobEvent#getTags}.
   *
   * <p>A tag may not be null, contain whitespace, or be more than 100 characters.
   * If a tag was already added, it won't be added again.
   *
   * <p>This method may be called more than once, but compile jobs that are already running
   * will not have the new tags.
   */
  public synchronized void addTags(String... tags) {
    this.tags.addAll(JobEvent.checkTags(Arrays.asList(tags)));
  }

  /**
   * Returns the arguments passed to {@link #parseArgs}.
   */
  ImmutableList<String> getArgs() {
    return args;
  }

  /**
   * Returns the tags passed to {@link #addTags}.
   */
  synchronized Set<String> getTags() {
    return ImmutableSet.copyOf(tags);
  }

  /**
   * A Java application that embeds Super Dev Mode can use this hook to find out
   * when compiles start and end.
   *
   * @deprecated replaced by {@link #setJobChangeListener}
   */
  @Deprecated
  public void setRecompileListener(RecompileListener listener) {
    this.recompileListener = listener == null ? RecompileListener.NONE : listener;
  }

  RecompileListener getRecompileListener() {
    return recompileListener;
  }

  /**
   * A Java application that embeds Super Dev Mode can use this hook to find out
   * when compile jobs change state.
   *
   * <p>Replaces {@link #setRecompileListener}
   */
  public void setJobChangeListener(JobChangeListener listener) {
    this.jobChangeListener = listener == null ? JobChangeListener.NONE : listener;
  }

  JobChangeListener getJobChangeListener() {
    return jobChangeListener;
  }

  /**
   * The top level of the directory tree where the code server keeps compiler output.
   */
  File getWorkDir() {
    return workDir;
  }

  /**
   * A directory where each module's files for launching Super Dev Mode should be written,
   * or null if not supplied.
   * (For example, nocache.js and public resource files will go here.)
   */
  File getLauncherDir() {
    return launcherDir;
  }

  /**
   * The names of the module that will be compiled (along with all its dependencies).
   */
  List<String> getModuleNames() {
    return moduleNames;
  }

  /**
   * Whether the codeServer should allow missing source directories.
   */
  boolean shouldAllowMissingSourceDir() {
    return allowMissingSourceDir;
  }

  /**
   * Compiles faster by creating a JavaScript file per class. Can't be turned on at the same time as
   * shouldCompileIncremental().
   */
  boolean isIncrementalCompileEnabled() {
    return incremental;
  }

  /**
   * Whether the codeServer should start without precompiling modules.
   */
  boolean getNoPrecompile() {
    return noPrecompile;
  }

  /**
   * The tree logger level.
   */
  TreeLogger.Type getLogLevel() {
    return logLevel;
  }

  /**
   * Java source level compatibility,
   */
  SourceLevel getSourceLevel() {
    return sourceLevel;
  }

  /**
   * If true, just compile the modules, then exit.
   */
  boolean isCompileTest() {
    return isCompileTest;
  }

  /**
   * The IP address where the code server should listen.
   */
  String getBindAddress() {
    return bindAddress;
  }

  int getCompileTestRecompiles() {
    return compileTestRecompiles;
  }

  /**
   * The hostname to put in a URL pointing to the code server.
   */
  String getPreferredHost() {
    return preferredHost;
  }

  /**
   * The port where the code server will listen for HTTP requests.
   */
  int getPort() {
    return port;
  }

  List<File> getSourcePath() {
    return sourcePath;
  }

  /**
   * If true, run the compiler in "strict" mode, which fails the compile if any Java file
   * cannot be compiled, whether or not it is used.
   */
  boolean isFailOnError() {
    return failOnError;
  }

  boolean shouldGenerateJsInteropExports() {
    return generateJsInteropExports;
  }

  WhitelistRegexFilter getJsInteropExportFilter() {
    return jsInteropExportFilter;
  }

  JsOutputOption getOutput() {
    if (output == null) {
      return isIncrementalCompileEnabled() ? JsOutputOption.OBFUSCATED : JsOutputOption.PRETTY;
    }
    return output;
  }

  ListMultimap<String, String> getProperties() {
    return properties;
  }

  public boolean isClosureFormattedOutput() {
    return closureFormattedOutput;
  }

  private class ArgProcessor extends ArgProcessorBase {

    public ArgProcessor() {
      registerHandler(new AllowMissingSourceDirFlag());
      registerHandler(new CompileTestFlag());
      registerHandler(new CompileTestRecompilesFlag());
      registerHandler(new FailOnErrorFlag());
      registerHandler(new ModuleNameArgument());
      registerHandler(new NoPrecompileFlag());
      registerHandler(new PortFlag());
      registerHandler(new SourceFlag());
      registerHandler(new WorkDirFlag());
      registerHandler(new LauncherDir());
      registerHandler(new ArgHandlerBindAddress(new OptionBindAddress() {
        @Override
        public String getBindAddress() {
          return Options.this.bindAddress;
        }

        @Override
        public String getConnectAddress() {
          return Options.this.preferredHost;
        }

        @Override
        public void setBindAddress(String bindAddress) {
          Options.this.bindAddress = bindAddress;
        }

        @Override
        public void setConnectAddress(String connectAddress) {
          Options.this.preferredHost = connectAddress;
        }
      }));
      registerHandler(new ArgHandlerScriptStyle(new OptionScriptStyle() {
        @Override
        public JsOutputOption getOutput() {
          return Options.this.output;
        }

        @Override
        public void setOutput(JsOutputOption output) {
          Options.this.output = output;
        }
      }));
      registerHandler(new ArgHandlerSetProperties(new OptionSetProperties() {

          @Override
        public void setPropertyValues(String name, Iterable<String> values) {
          properties.replaceValues(name, values);
        }

          @Override
        public ListMultimap<String, String> getProperties() {
          return properties;
        }

      }));
      registerHandler(new ArgHandlerIncrementalCompile(new OptionIncrementalCompile() {
        @Override
        public boolean isIncrementalCompileEnabled() {
          return incremental;
        }

        @Override
        public void setIncrementalCompileEnabled(boolean enabled) {
          incremental = enabled;
        }
      }));
      registerHandler(new ArgHandlerSourceLevel(new OptionSourceLevel() {
        @Override
        public SourceLevel getSourceLevel() {
          return sourceLevel;
        }

        @Override
        public void setSourceLevel(SourceLevel sourceLevel) {
          Options.this.sourceLevel = sourceLevel;
        }
      }));
      registerHandler(new ArgHandlerLogLevel(new OptionLogLevel() {
        @Override
        public TreeLogger.Type getLogLevel() {
          return logLevel;
        }

        @Override
        public void setLogLevel(TreeLogger.Type logLevel) {
          Options.this.logLevel = logLevel;
        }
      }));
      OptionGenerateJsInteropExports optionGenerateJsInteropExport =
          new OptionGenerateJsInteropExports() {
            @Override
            public boolean shouldGenerateJsInteropExports() {
              return Options.this.generateJsInteropExports;
            }
            @Override
            public void setGenerateJsInteropExports(boolean generateExports) {
              Options.this.generateJsInteropExports = generateExports;
            }
            @Override
            public WhitelistRegexFilter getJsInteropExportFilter() {
              return Options.this.jsInteropExportFilter;
            }
          };
      registerHandler(new ArgHandlerGenerateJsInteropExports(optionGenerateJsInteropExport));
      registerHandler(new ArgHandlerFilterJsInteropExports(optionGenerateJsInteropExport));
      registerHandler(new ArgHandlerMethodNameDisplayMode(new OptionMethodNameDisplayMode() {
        @Override
        public OptionMethodNameDisplayMode.Mode getMethodNameDisplayMode() {
          return Options.this.methodNameDisplayMode;
        }

        @Override
        public void setMethodNameDisplayMode(Mode mode) {
          Options.this.methodNameDisplayMode = mode;
        }
      }));
      registerHandler(new ArgHandlerClosureFormattedOutput(new OptionClosureFormattedOutput() {
        @Override
        public boolean isClosureCompilerFormatEnabled() {
          return Options.this.closureFormattedOutput;
        }

        @Override
        public void setClosureCompilerFormatEnabled(boolean enabled) {
          Options.this.closureFormattedOutput = enabled;
        }
      }));
    }

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

  private class NoPrecompileFlag extends ArgHandlerFlag {

    @Override
    public String getLabel() {
      return "precompile";
    }

    @Override
    public String getPurposeSnippet() {
      return "Precompile modules.";
    }

    @Override
    public boolean setFlag(boolean value) {
      noPrecompile = !value;
      return true;
    }

    @Override
    public boolean getDefaultValue() {
      return !noPrecompile;
    }
  }

  private class CompileTestFlag extends ArgHandlerFlag {

    @Override
    public String getLabel() {
      return "compileTest";
    }

    @Override
    public String getPurposeSnippet() {
      return "Exits after compiling the modules. The exit code will be 0 if the compile succeeded.";
    }

    @Override
    public boolean setFlag(boolean value) {
      isCompileTest = value;
      return true;
    }

    @Override
    public boolean getDefaultValue() {
      return isCompileTest;
    }
  }

  private class CompileTestRecompilesFlag extends ArgHandlerInt {

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

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

    @Override
    public String getPurpose() {
      return "The number of times to recompile (after the first one) during a compile test.";
    }

    @Override
    public void setInt(int value) {
      compileTestRecompiles = value;
    }
  }

  private class PortFlag extends ArgHandlerInt {

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

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


    @Override
    public String getPurpose() {
      return "The port where the code server will run.";
    }

    @Override
    public void setInt(int newValue) {
      port = newValue;
    }
  }

  private class WorkDirFlag extends ArgHandlerDir {

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

    @Override
    public String getPurpose() {
      return "The root of the directory tree where the code server will"
          + "write compiler output. If not supplied, a temporary directory"
          + "will be used.";
    }

    @Override
    public void setDir(File newValue) {
      workDir = newValue;
    }
  }

  private class FailOnErrorFlag extends ArgHandlerFlag {

    FailOnErrorFlag() {
      // Backward compatibility with -strict in the regular compiler.
      addTagValue("-strict", true);
    }

    @Override
    public String getLabel() {
      return "failOnError";
    }

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

    @Override
    public String getPurposeSnippet() {
      return "Stop compiling if a module has a Java file with a compile error, even if unused.";
    }

    @Override
    public boolean setFlag(boolean value) {
      failOnError = value;
      return true;
    }
  }

  private class AllowMissingSourceDirFlag extends ArgHandlerFlag {

    @Override
    public String getLabel() {
      return "allowMissingSrc";
    }

    @Override
    public String getPurposeSnippet() {
      return "Allows -src flags to reference missing directories.";
    }

    @Override
    public boolean setFlag(boolean value) {
      allowMissingSourceDir = value;
      return true;
    }

    @Override
    public boolean getDefaultValue() {
      return allowMissingSourceDir;
    }
  }

  private class SourceFlag extends ArgHandler {

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

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

    @Override
    public String getPurpose() {
      return "A directory containing GWT source to be prepended to the classpath for compiling.";
    }

    @Override
    public int handle(String[] args, int startIndex) {
      if (startIndex + 1 >= args.length) {
        System.err.println(getTag() + " should be followed by the name of a directory");
        return -1;
      }

      File candidate = new File(args[startIndex + 1]);
      if (!allowMissingSourceDir && !candidate.isDirectory()) {
        System.err.println("not a directory: " + candidate);
        return -1;
      }

      sourcePath.add(candidate);
      return 1;
    }
  }

  private class LauncherDir extends ArgHandler {

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

    @Override
    public String[] getTags() {
      // add an alias since in DevMode this was "-war"
      return new String[] {getTag(), "-war"};
    }

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

    @Override
    public String getPurpose() {
      return "An output directory where files for launching Super Dev Mode will be written. "
          + "(Optional.)";
    }

    @Override
    public int handle(String[] args, int startIndex) {
      if (startIndex + 1 >= args.length) {
        System.err.println(getTag() + " should be followed by the name of a directory");
        return -1;
      }

      File candidate = new File(args[startIndex + 1]);
      if (candidate.exists() && !candidate.isDirectory()) {
        System.err.println("not a directory: " + candidate);
        return -1;
      }

      launcherDir = candidate;
      return 1;
    }
  }

  private class ModuleNameArgument extends ArgHandlerExtra {

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

    @Override
    public String getPurpose() {
      return "The GWT modules that the code server should compile. (Example: com.example.MyApp)";
    }

    @Override
    public boolean addExtraArg(String arg) {
      if (!ModuleDef.isValidModuleName(arg)) {
        System.err.println("Invalid module name: '" + arg + "'");
        return false;
      }
      moduleNames.add(arg);
      return true;
    }
  }

  public OptionMethodNameDisplayMode.Mode getMethodNameDisplayMode() {
    return methodNameDisplayMode;
  }
}
