/*
 * 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.dev.ArgProcessorBase;
import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
import com.google.gwt.dev.util.arg.OptionSourceLevel;
import com.google.gwt.dev.util.arg.SourceLevel;
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 com.google.gwt.util.tools.ArgHandlerString;

import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * 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 boolean noPrecompile = false;
  private boolean isCompileTest = false;
  private File workDir;
  private List<String> moduleNames = new ArrayList<String>();
  private boolean allowMissingSourceDir = false;
  private final List<File> sourcePath = new ArrayList<File>();
  private String bindAddress = "127.0.0.1";
  private String preferredHost = "localhost";
  private int port = 9876;
  private RecompileListener recompileListener = RecompileListener.NONE;
  // Use the same default as the GWT compiler.
  private SourceLevel sourceLevel = SourceLevel.DEFAULT_SOURCE_LEVEL;
  private boolean strictResources = false;

  /**
   * 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) {
    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;
    }

    return true;
  }

  /**
   * A Java application that embeds Super Dev Mode can use this hook to find out
   * when compiles start and end.
   */
  public void setRecompileListener(RecompileListener recompileListener) {
    this.recompileListener = recompileListener;
  }

  RecompileListener getRecompileListener() {
    return recompileListener;
  }

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

  /**
   * 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;
  }

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

  /**
   * 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;
  }

  /**
   * 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;
  }

  /**
   * Whether to implicitly import client and public directories when no explicit imports exist.
   */
  boolean enforceStrictResources() {
    return strictResources;
  }

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

  private class ArgProcessor extends ArgProcessorBase {

    public ArgProcessor() {
      registerHandler(new NoPrecompileFlag());
      registerHandler(new CompileTestFlag());
      registerHandler(new BindAddressFlag());
      registerHandler(new PortFlag());
      registerHandler(new WorkDirFlag());
      registerHandler(new AllowMissingSourceDirFlag());
      registerHandler(new SourceFlag());
      registerHandler(new ModuleNameArgument());
      registerHandler(new StrictResourcesFlag());
      registerHandler(new ArgHandlerSourceLevel(new OptionSourceLevel() {
        @Override
        public SourceLevel getSourceLevel() {
          return sourceLevel;
        }

        @Override
        public void setSourceLevel(SourceLevel sourceLevel) {
          Options.this.sourceLevel = sourceLevel;
        }
      }));
    }

    @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 BindAddressFlag extends ArgHandlerString {

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

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

    @Override
    public String getPurpose() {
      return "The ip address of the code server. Defaults to 127.0.0.1.";
    }

    @Override
    public boolean setString(String newValue) {
      try {
        InetAddress bindAddress = InetAddress.getByName(newValue);
        if (bindAddress.isAnyLocalAddress()) {
          preferredHost = InetAddress.getLocalHost().getHostName();
        } else {
          preferredHost = newValue;
        }
      } catch (UnknownHostException e) {
        System.err.println("Can't resolve bind address: " + newValue);
        return false;
      }

      // Save the original since there's no way to get it back from an InetAddress.
      bindAddress = newValue;
      return true;
    }
  }

  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 StrictResourcesFlag extends ArgHandlerFlag {

    public StrictResourcesFlag() {
      addTagValue("-XstrictResources", true);
    }

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

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

    @Override
    public String getPurposeSnippet() {
      return "Avoid adding implicit dependencies on \"client\" and \"public\" for "
          + "modules that don't define any dependencies.";
    }

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

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

  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 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) {
      moduleNames.add(arg);
      return true;
    }
  }
}
