/*
 * 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.tools.apichecker;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.dev.javac.Shared;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.SourceLevel;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.util.tools.ArgHandlerFlag;
import com.google.gwt.util.tools.ArgHandlerString;
import com.google.gwt.util.tools.ToolBase;

import com.google.gwt.thirdparty.apache.ant.types.ZipScanner;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * {@link ApiCompatibilityChecker} Main class to check if the new API is
 * compatible with the existing API.
 * 
 * <p>
 * To compute API diffs, follow these 2 steps:
 * <ol>
 * <li>for each of the two repositories, construct an {@link ApiContainer}
 * <li>call getApiDiff on the {@code ApiDiffGenerator}
 * </ol>
 * </p>
 * 
 * <p>
 * An {@code ApiContainer} object is a list of {@link ApiPackage} objects.
 * {@code ApiPackage} objects themselves are list of {@link ApiClass} objects.
 * {@code ApiClass} objects contain list of {@code ApiConstructor},
 * {@code ApiMethod}, and {@code JField} objects.
 * </p>
 * 
 * <p>
 * Each {@code ApiDiffGenerator} object computes the list of intersecting and
 * missing {@link ApiPackageDiffGenerator} objects. Each
 * {@code ApiPackageDiffGenerator} object in turn computes the list of
 * intersecting and missing {@link ApiClassDiffGenerator} objects. Each
 * {@code ApiClassDiffGenerator} object in turn computes the list of
 * intersecting and missing API members. The members are represented by
 * {@link ApiConstructor} for constructors, {@link ApiMethod} for methods, and
 * {@link ApiField} for fields.
 * </p>
 * 
 * <p>
 * For each intersecting API member, a list of {@link ApiChange} objects is
 * stored. Each ApiChange object encodes a specific {@code ApiChange} like
 * adding the 'final' keyword to the API member.
 * 
 */
public class ApiCompatibilityChecker extends ToolBase {

  // TODO(amitmanjhi): check gwt's dev/core/src files. Would need the ability to
  // build TypeOracle from class files

  // TODO(amitmanjhi): better handling of exceptions and exception-chaining.

  static class FileResource extends Resource {
    private final File file;
    private final String path;

    public FileResource(File file, String path) {
      this.file = file;
      this.path = path;
      assert path.endsWith(".java");
      assert file.getAbsolutePath().endsWith(path);
    }

    @Override
    public long getLastModified() {
      return file.lastModified();
    }

    @Override
    public String getLocation() {
      return file.getAbsolutePath();
    }

    @Override
    public String getPath() {
      return path;
    }

    @Override
    public InputStream openContents() {
      try {
        return new FileInputStream(file);
      } catch (FileNotFoundException e) {
        throw new RuntimeException("Unable to open file '" + file.getAbsolutePath() + "'", e);
      }
    }

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

  static class StaticResource extends Resource {

    private final long lastModified;
    private final String source;
    private final String typeName;

    public StaticResource(String typeName, String source, long lastModified) {
      this.typeName = typeName;
      this.source = source;
      this.lastModified = lastModified;
    }

    @Override
    public long getLastModified() {
      return lastModified;
    }

    @Override
    public String getLocation() {
      return "/mock/" + getPath();
    }

    @Override
    public String getPath() {
      return Shared.toPath(typeName);
    }

    @Override
    public InputStream openContents() {
      return new ByteArrayInputStream(Util.getBytes(source));
    }

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

  /**
   * Class that specifies a set of
   * {@link com.google.gwt.dev.javac.CompilationUnit CompilationUnit} read from
   * jar files.
   */
  private static class JarFileResources extends Resources {
    private static final String MOCK_PREFIX = "/mock/";
    private static final int MOCK_PREFIX_LENGTH = MOCK_PREFIX.length();

    private final ZipScanner excludeScanner;
    private final Set<String> includedPaths;
    private final JarFile jarFiles[];
    private Set<Resource> resources = null;

    JarFileResources(JarFile[] jarFiles, Set<String> includedPaths, Set<String> excludedPaths,
        TreeLogger logger) {
      super(logger);
      this.jarFiles = jarFiles;
      this.includedPaths = includedPaths;

      // initialize the ant scanner
      excludeScanner = new ZipScanner();
      List<String> list = new ArrayList<String>(excludedPaths);
      excludeScanner.setIncludes(list.toArray(new String[list.size()]));
      excludeScanner.addDefaultExcludes();
      excludeScanner.setCaseSensitive(true);
      excludeScanner.init();
    }

    @Override
    public Set<Resource> getResources() throws IOException {
      if (resources != null) {
        return resources;
      }

      resources = new HashSet<Resource>();
      for (JarFile jarFile : jarFiles) {
        Enumeration<JarEntry> entries = jarFile.entries();
        while (entries.hasMoreElements()) {
          JarEntry jarEntry = entries.nextElement();
          String fileName = jarEntry.toString();
          if (fileName.startsWith(MOCK_PREFIX)) {
            fileName = fileName.substring(MOCK_PREFIX_LENGTH);
          }
          if (fileName.endsWith(".java") && isIncluded(fileName)) {
            // add this compilation unit
            String fileContent = getFileContentsFromJar(jarFile, jarEntry);
            String packageName = extractPackageName(new StringReader(fileContent));
            if (packageName == null) {
              logger.log(TreeLogger.WARN, "Not adding file = " + fileName
                  + ", because packageName = null", null);
            } else {
              if (isValidPackage(packageName, fileName)) {
                // Add if package and fileNames are okay
                long lastModified = jarEntry.getTime();
                if (lastModified < 0) {
                  lastModified = System.currentTimeMillis();
                }
                resources.add(new StaticResource(packageName + "." + getClassName(fileName),
                    fileContent, lastModified));
                logger.log(TreeLogger.DEBUG, "adding pkgName = " + packageName + ", file = "
                    + fileName, null);
              } else {
                logger.log(TreeLogger.SPAM, " not adding file " + fileName, null);
              }
            }
          }
        }
      }
      return resources;
    }

    String getFileContentsFromJar(JarFile jarFile, JarEntry jarEntry) throws IOException {
      StringBuffer fileContent = new StringBuffer();
      InputStream is = jarFile.getInputStream(jarEntry);
      BufferedInputStream bis = new BufferedInputStream(is);
      int length = 500;
      byte buf[] = new byte[length];
      int count = 0;
      while ((count = bis.read(buf, 0, length)) != -1) {
        fileContent.append(new String(buf, 0, count));
        buf = new byte[length];
      }
      bis.close();
      is.close();
      return fileContent.toString();
    }

    private String getClassName(String fileName) {
      int index = fileName.lastIndexOf("/");
      int endOffset = 0;
      if (fileName.endsWith(".java")) {
        endOffset = 5;
      }
      return fileName.substring(index + 1, fileName.length() - endOffset);
    }

    private boolean isIncluded(String fileName) {
      if (excludeScanner.match(fileName)) {
        logger.log(TreeLogger.SPAM, fileName + " is excluded");
        return false;
      }
      for (String includedPath : includedPaths) {
        if (fileName.startsWith(includedPath)) {
          logger.log(TreeLogger.SPAM, fileName + " is not excluded, and is included by "
              + includedPath);
          return true;
        }
      }
      return false;
    }
  }

  /**
   * Abstract internal class that specifies a set of
   * {@link com.google.gwt.dev.javac.CompilationUnit CompilationUnit}.
   */
  private abstract static class Resources {
    protected final TreeLogger logger;

    Resources(TreeLogger logger) {
      this.logger = logger;
    }

    public abstract Set<Resource> getResources() throws NotFoundException, IOException,
        UnableToCompleteException;

    // TODO (amitmanjhi): remove this code. use TypeOracle functionality
    // instead.
    protected String extractPackageName(Reader reader) throws IOException {
      BufferedReader br = new BufferedReader(reader);
      String str = null;
      while ((str = br.readLine()) != null) {
        if (str.indexOf("package") != 0) {
          continue;
        }
        String parts[] = str.split("[\b\t\n\r ]+");
        if ((parts.length == 2) && parts[0].equals("package")) {
          return parts[1].substring(0, parts[1].length() - 1); // the ; char
        }
      }
      return null;
    }

    protected File getFileFromName(String tag, String pathName) throws FileNotFoundException {
      File file = new File(pathName);
      if (!file.exists()) {
        throw new FileNotFoundException(tag + "file " + pathName + " not found");
      }
      return file;
    }

    // TODO (amitmanjhi): remove this code. use TypeOracle functionality
    // instead.
    protected boolean isValidPackage(String packageName, String filePath) {
      logger
          .log(TreeLogger.SPAM, "packageName = " + packageName + ", filePath = " + filePath, null);
      if (packageName == null) {
        return false;
      }
      int lastSlashPosition = filePath.lastIndexOf("/");
      if (lastSlashPosition == -1) {
        return false;
      }
      String dirPath = filePath.substring(0, lastSlashPosition);
      String packageNameAsPath = packageName.replace('.', '/');
      logger.log(TreeLogger.SPAM, "packageNameAsPath " + packageNameAsPath + ", dirPath = "
          + dirPath, null);
      return dirPath.endsWith(packageNameAsPath);
    }
  }

  /**
   * Class that specifies a set of
   * {@link com.google.gwt.dev.javac.CompilationUnit CompilationUnit} read from
   * the file-system.
   */
  private static class SourceFileResources extends Resources {
    private final ZipScanner excludeScanner;
    private final Set<File> includedPaths;
    private Set<Resource> units = null;

    SourceFileResources(String dirRoot, Set<String> includedPathsAsString,
        Set<String> excludedPathsAsString, TreeLogger logger) throws FileNotFoundException,
        IOException {
      super(logger);
      if (dirRoot == null) {
        dirRoot = "";
      }
      includedPaths = new HashSet<File>();
      for (String includedPath : includedPathsAsString) {
        includedPaths.add(getFileFromName("source file: ", dirRoot + includedPath));
      }

      String fullExcludedPaths[] = new String[excludedPathsAsString.size()];
      int count = 0;
      String dirRootAbsolutePath = getFileFromName("dirRoot: ", dirRoot).getAbsolutePath();
      if (dirRootAbsolutePath.startsWith("/") || dirRootAbsolutePath.startsWith("\\")) {
        // Remove initial File.Separator to work with ant versions above and below 1.8.1.
        dirRootAbsolutePath = dirRootAbsolutePath.substring(1);
      }
      for (String excludedPath : excludedPathsAsString) {
        fullExcludedPaths[count++] = dirRootAbsolutePath + "/" + excludedPath;
      }

      // initialize the ant scanner
      excludeScanner = new ZipScanner();
      if (fullExcludedPaths.length > 0) {
        excludeScanner.setIncludes(fullExcludedPaths);
      }
      excludeScanner.addDefaultExcludes();
      excludeScanner.setCaseSensitive(true);
      excludeScanner.init();
    }

    @Override
    public Set<Resource> getResources() throws NotFoundException, IOException,
        UnableToCompleteException {
      if (units != null) {
        return units;
      }

      units = new HashSet<Resource>();
      for (File sourceFile : includedPaths) {
        updateCompilationUnitsInPath(sourceFile);
      }
      return units;
    }

    private boolean isExcludedFile(String fileName) {
      String pattern = "file:";
      if (fileName.indexOf(pattern) == 0) {
        fileName = fileName.substring(pattern.length());
      }
      if (fileName.startsWith("/") || fileName.startsWith("\\")) {
        // Remove initial File.Separator to work with ant versions above and below 1.8.1.
        fileName = fileName.substring(1);
      }
      return excludeScanner.match(fileName);
    }

    private void updateCompilationUnitsInPath(File sourcePathEntry) throws NotFoundException,
        IOException, UnableToCompleteException {
      logger.log(TreeLogger.SPAM, "entering addCompilationUnitsInPath, file = " + sourcePathEntry,
          null);
      File[] files = sourcePathEntry.listFiles();
      if (files == null) { // No files found.
        return;
      }

      for (int i = 0; i < files.length; i++) {
        final File file = files[i];
        logger.log(TreeLogger.SPAM, "deciding the fate of file " + file, null);
        // Ignore files like .svn and .cvs
        if (file.getName().startsWith(".") || file.getName().equals("CVS")) {
          continue;
        }
        if (isExcludedFile(file.getAbsolutePath())) {
          // do not process the subtree
          logger.log(TreeLogger.DEBUG, "not traversing " + file.toURI().toURL(), null);
          continue;
        }
        if (file.isFile()) {
          String fileName = file.getName();
          if (file.getName().endsWith("java")) {
            String className = file.getName().substring(0, fileName.length() - 5);
            String pkgName = extractPackageName(new FileReader(file));
            if (pkgName == null) {
              logger.log(TreeLogger.WARN, "Not adding file = " + file.toString()
                  + ", because packageName = null", null);
            } else {
              if (isValidPackage(pkgName, sourcePathEntry.toURI().toURL().toString())) {
                // Add if the package and fileNames are okay
                String typeName = Shared.makeTypeName(pkgName, className);
                units.add(new FileResource(file, Shared.toPath(typeName)));
                logger.log(TreeLogger.DEBUG, "adding pkgName = " + pkgName + ", file = "
                    + file.toString(), null);
              } else {
                logger.log(TreeLogger.SPAM, " not adding file " + file.toURI().toURL(), null);
              }
            }
          }
        } else {
          // Recurse into subDirs
          updateCompilationUnitsInPath(file);
        }
      }
    }
  }

  // currently doing only source_compatibility. true by default.
  public static final boolean API_SOURCE_COMPATIBILITY = true;

  /**
   * Prints which class the member was declared in plus the string message in
   * ApiChange, false by default.
   */
  public static boolean DEBUG = false;

  public static final boolean DEBUG_DUPLICATE_REMOVAL = false;

  /**
   * Flag for filtering duplicates, true by default. Just for debugging in rare
   * cases.
   */
  public static final boolean FILTER_DUPLICATES = true;

  /**
   * Print APIs common in the two repositories. Should be false by default.
   */
  public static final boolean PRINT_COMPATIBLE = false;
  /**
   * Print APIs common in the two repositories. Should be false by default.
   */
  public static final boolean PRINT_COMPATIBLE_WITH = false;

  /**
   * Flag for debugging whether typeOracle builds.
   */
  public static final boolean PROCESS_EXISTING_API = true;

  /**
   * Flag for debugging whether typeOracle builds.
   */
  public static final boolean PROCESS_NEW_API = true;

  // true by default
  public static final boolean REMOVE_NON_SUBCLASSABLE_ABSTRACT_CLASS_FROM_API = true;

  // remove duplicates by default
  public static Collection<ApiChange> getApiDiff(ApiContainer newApi, ApiContainer existingApi,
      Set<String> whiteList) throws NotFoundException {
    ApiDiffGenerator apiDiff = new ApiDiffGenerator(newApi, existingApi);
    return getApiDiff(apiDiff, whiteList, FILTER_DUPLICATES);
  }

  public static void main(String args[]) {
    try {
      ApiCompatibilityChecker checker = new ApiCompatibilityChecker();
      if (!checker.processArgs(args)) {
        // if we couldn't parse arguments, return non-zero so the build breaks
        System.exit(1);
      }

      ApiContainer newApi = null, existingApi = null;

      AbstractTreeLogger logger = new PrintWriterTreeLogger();
      logger.setMaxDetail(checker.type);
      logger.log(TreeLogger.INFO, "gwtDevJar = " + checker.gwtDevJar + ", userJar = "
          + checker.gwtUserJar + ", refjars = " + Arrays.toString(checker.refJars)
          + ", logLevel = " + checker.type + ", printAllApi = " + checker.printAllApi, null);

      Set<String> excludedPackages = checker.getSetOfExcludedPackages(checker.configProperties);
      if (PROCESS_NEW_API) {
        Set<Resource> resources = new HashSet<Resource>();
        resources.addAll(new SourceFileResources(checker.configProperties
            .getProperty("dirRoot_new"), checker.getConfigPropertyAsSet("sourceFiles_new"), checker
            .getConfigPropertyAsSet("excludedFiles_new"), logger).getResources());
        resources.addAll(checker.getJavaxValidationCompilationUnits(logger));
        resources.addAll(checker.getGwtCompilationUnits(logger));
        SourceLevel newSourceLevel =
            SourceLevel.fromString(checker.configProperties.getProperty("sourceLevel_new"));
        newApi =
            new ApiContainer(checker.configProperties.getProperty("name_new"), resources,
                excludedPackages, logger, newSourceLevel);
        if (checker.printAllApi) {
          logger.log(TreeLogger.INFO, newApi.getApiAsString());
        }
      }
      if (PROCESS_EXISTING_API) {
        Set<Resource> resources = new HashSet<Resource>();
        if (checker.refJars == null) {
          resources.addAll(new SourceFileResources(checker.configProperties
              .getProperty("dirRoot_old"), checker.getConfigPropertyAsSet("sourceFiles_old"),
              checker.getConfigPropertyAsSet("excludedFiles_old"), logger).getResources());
        } else {
          resources.addAll(new JarFileResources(checker.refJars, checker
              .getConfigPropertyAsSet("sourceFiles_old"), checker
              .getConfigPropertyAsSet("excludedFiles_old"), logger).getResources());
        }
        resources.addAll(checker.getJavaxValidationCompilationUnits(logger));
        resources.addAll(checker.getGwtCompilationUnits(logger));
        SourceLevel oldSourceLevel =
            SourceLevel.fromString(checker.configProperties.getProperty("sourceLevel_old"));
        existingApi =
            new ApiContainer(checker.configProperties.getProperty("name_old"), resources,
                excludedPackages, logger, oldSourceLevel);
        if (checker.printAllApi) {
          logger.log(TreeLogger.INFO, existingApi.getApiAsString());
        }
      }

      if (PROCESS_NEW_API && PROCESS_EXISTING_API) {
        Collection<ApiChange> apiDifferences = getApiDiff(newApi, existingApi, checker.whiteList);
        for (ApiChange apiChange : apiDifferences) {
          System.out.println(apiChange);
        }
        if (apiDifferences.size() == 0) {
          System.out.println("API compatibility check SUCCESSFUL");
        } else {
          System.out.println("API compatibility check FAILED");
        }
        System.exit(apiDifferences.size() == 0 ? 0 : 1);
      }

    } catch (Throwable t) {
      // intercepting all exceptions in main, because I have to exit with -1 so
      // that the build breaks.
      try {
        t.printStackTrace();
        System.err
            .println("To view the help for this tool, execute this tool without any arguments");
      } finally {
        System.exit(-1);
      }
    }
  }

  // interface for testing, since do not want to build ApiDiff frequently
  static Collection<ApiChange> getApiDiff(ApiDiffGenerator apiDiff, Set<String> whiteList,
      boolean removeDuplicates) throws NotFoundException {
    Collection<ApiChange> collection = apiDiff.getApiDiff();
    if (removeDuplicates) {
      collection = apiDiff.removeDuplicates(collection);
    }
    Set<String> matchedWhiteList = new HashSet<String>();

    Collection<ApiChange> prunedCollection = new ArrayList<ApiChange>();
    for (ApiChange apiChange : collection) {
      String apiChangeAsString = apiChange.getStringRepresentationWithoutMessage();
      apiChangeAsString = apiChangeAsString.trim();
      if (whiteList.contains(apiChangeAsString)) {
        matchedWhiteList.add(apiChangeAsString);
        continue;
      }
      // check for Status.Compatible and Status.Compatible_with
      if (!PRINT_COMPATIBLE && apiChange.getStatus().equals(ApiChange.Status.COMPATIBLE)) {
        continue;
      }
      if (!PRINT_COMPATIBLE_WITH && apiChange.getStatus().equals(ApiChange.Status.COMPATIBLE_WITH)) {
        continue;
      }
      prunedCollection.add(apiChange);
    }
    whiteList.removeAll(matchedWhiteList);
    if (whiteList.size() > 0) {
      List<String> al = new ArrayList<String>(whiteList);
      Collections.sort(al);
      System.err.println("ApiChanges [");
      for (String apiChange : al) {
        System.err.println(apiChange);
      }
      System.err.println("],  not found. Are you using a properly formatted configuration file?");
    }
    List<ApiChange> apiChangeList = new ArrayList<ApiChange>(prunedCollection);
    Collections.sort(apiChangeList);
    return apiChangeList;
  }

  private Properties configProperties;
  private JarFile[] extraSourceJars;
  private JarFile gwtDevJar;
  private JarFile gwtUserJar;

  // prints the API of the two containers, false by default.
  private boolean printAllApi = false;
  private JarFile refJars[];
  // default log output
  private TreeLogger.Type type = TreeLogger.WARN;
  private Set<String> whiteList;

  protected ApiCompatibilityChecker() {

    /*
     * register handlers for gwtDevJar, gwtUserJar, refJar, logLevel,
     * printAllApi, configProperties
     */

    // handler for gwtDevJar
    registerHandler(new ArgHandlerString() {

      @Override
      public String getPurpose() {
        return "Path of the gwt dev jar";
      }

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

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

      @Override
      public boolean setString(String str) {
        gwtDevJar = getJarFromString(str);
        return gwtDevJar != null;
      }
    });

    // handler for gwtUserJar
    registerHandler(new ArgHandlerString() {

      @Override
      public String getPurpose() {
        return "Path of the gwt user jar";
      }

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

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

      @Override
      public boolean setString(String str) {
        gwtUserJar = getJarFromString(str);
        return gwtUserJar != null;
      }
    });

    // handler for refJar
    registerHandler(new ArgHandlerString() {
      @Override
      public String getPurpose() {
        return "Path of the reference jar";
      }

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

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

      @Override
      public boolean setString(String str) {
        String refJarStrings[] = str.split(System.getProperty("path.separator"));
        refJars = new JarFile[refJarStrings.length];
        int count = 0;
        for (String refJarString : refJarStrings) {
          refJars[count++] = getJarFromString(refJarString);
          if (refJars[count - 1] == null) {
            return false; // bail-out early
          }
        }
        return refJars != null;
      }
    });

    // handler for logLevel
    registerHandler(new ArgHandlerString() {

      @Override
      public String getPurpose() {
        return "Sets the log level of the TreeLogger";
      }

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

      @Override
      public String[] getTagArgs() {
        String values[] = new String[TreeLogger.Type.values().length];
        int count = 0;
        for (TreeLogger.Type tempType : TreeLogger.Type.values()) {
          values[count++] = tempType.name();
        }
        return values;
      }

      @Override
      public boolean setString(String str) {
        for (TreeLogger.Type tempType : TreeLogger.Type.values()) {
          if (tempType.name().equals(str)) {
            type = tempType;
            return true;
          }
        }
        return false;
      }

    });

    // handler for printAllApi
    registerHandler(new ArgHandlerFlag() {

      @Override
      public String getPurposeSnippet() {
        return "Prints all api.";
      }

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

      @Override
      public boolean setFlag(boolean enabled) {
        printAllApi = enabled;
        return true;
      }

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

    // handler for configFile
    registerHandler(new ArgHandlerString() {

      @Override
      public String getPurpose() {
        return "Path of the configuration file";
      }

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

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

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

      @Override
      public boolean setString(String str) {
        setPropertiesAndWhitelist(str);
        return configProperties != null && whiteList != null;
      }
    });

    registerHandler(new ArgHandlerString() {

      @Override
      public String getPurpose() {
        return "The location of the javax.validation sources";
      }

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

      @Override
      public String[] getTagArgs() {
        return new String[] {"jar1.jar:jar2.jar"};
      }

      @Override
      public boolean setString(String str) {
        boolean success = true;
        String[] parts = str.split(System.getProperty("path.separator"));
        extraSourceJars = new JarFile[parts.length];
        for (int i = 0, j = parts.length; i < j; i++) {
          extraSourceJars[i] = getJarFromString(parts[i]);
        }
        return success;
      }
    });
  }

  @Override
  public void printHelp() {
    super.printHelp();
    StringBuffer sb = new StringBuffer();
    sb.append("\n");
    sb.append("The config file must specify two repositories of java source files: ");
    sb.append("'_old' and '_new', which are to be compared for API source compatibility.\n");
    sb.append("An optional whitelist is present at the end of ");
    sb.append("the config file. The format of the whitelist is same as the output of ");
    sb.append("the tool without the whitelist.\n");
    sb.append("Each repository is specified by the following four properties:\n");
    sb.append("name             specifies how the api should be refered to in the output\n");
    sb.append("dirRoot          optional argument that specifies the base directory of all other file/directory names\n");
    sb.append("sourceFiles      a colon-separated list of files/directories that specify the roots of the filesystem trees to be included.\n");
    sb.append("excludeFiles     a colon-separated lists of ant patterns to exclude");
    sb.append("sourceLevel      Java source level compatibility");

    sb.append("\n\n");
    sb.append("Example api.conf file:\n");
    sb.append("name_old         gwtEmulator");
    sb.append("\n");
    sb.append("dirRoot_old      ./");
    sb.append("\n");
    sb.append("sourceFiles_old  dev/core/super:user/super:user/src");
    sb.append("\n");
    sb.append("excludeFiles_old user/super/com/google/gwt/junit/*.java");
    sb.append("\n\n");

    sb.append("name_new         gwtEmulatorCopy");
    sb.append("\n");
    sb.append("dirRoot_new      ../gwt-14/");
    sb.append("\n");
    sb.append("sourceFiles_new  dev/core:user/super:user/src");
    sb.append("\n");
    sb.append("excludeFiles_new user/super/com/google/gwt/junit/*.java");
    sb.append("\n\n");

    System.err.println(sb.toString());
  }

  protected JarFile getJarFromString(String str) {
    try {
      return new JarFile(str);
    } catch (IOException ex) {
      System.err.println("exception in getting jar from fileName: " + str + ", message: "
          + ex.getMessage());
      return null;
    }
  }

  protected void setPropertiesAndWhitelist(String fileName) throws IllegalArgumentException {
    try {
      // load config properties
      FileInputStream fis = new FileInputStream(fileName);
      configProperties = new Properties();
      configProperties.load(fis);
      fis.close();

      // load whitelist
      FileReader fr = new FileReader(fileName);
      whiteList = readWhiteListFromFile(fr);
      fr.close();
    } catch (IOException ex) {
      System.err.println("Have you specified the path of the config file correctly?");
      throw new IllegalArgumentException(ex);
    }
  }

  private Set<String> getConfigPropertyAsSet(String key) {
    Set<String> set = new HashSet<String>();
    String propertyValue = configProperties.getProperty(key);
    if (propertyValue == null) {
      return set;
    }
    for (String element : propertyValue.split(":")) {
      element = element.trim();
      set.add(element);
    }
    return set;
  }

  private Set<Resource> getGwtCompilationUnits(TreeLogger logger) throws FileNotFoundException,
      IOException, NotFoundException, UnableToCompleteException {
    Set<Resource> resources = new HashSet<Resource>();
    if (gwtDevJar == null || gwtUserJar == null) {
      if (gwtDevJar != null) {
        System.err.println("Argument gwtUserJar must be provided for gwtDevJar to be used");
      }
      if (gwtUserJar != null) {
        System.err.println("Argument gwtDevJar must be provided for gwtUserJar to be used");
      }
      return resources;
    }
    // gwt-user.jar
    Set<String> gwtIncludedPaths =
        new HashSet<String>(Arrays.asList(new String[] {"com/google/gwt", "com/google/web"}));
    Set<String> gwtExcludedPaths =
        new HashSet<String>(
            Arrays
                .asList(new String[] {
                    "com/google/gwt/benchmarks",
                    "com/google/gwt/i18n/rebind",
                    "com/google/gwt/i18n/tools",
                    "com/google/gwt/json",
                    "com/google/gwt/junit",
                    "com/google/gwt/user/client/rpc/core/java/util/LinkedHashMap_CustomFieldSerializer.java",
                    "com/google/gwt/user/rebind", "com/google/gwt/user/server",
                    "com/google/gwt/user/tools",}));
    Resources cu =
        new JarFileResources(new JarFile[] {gwtUserJar}, gwtIncludedPaths, gwtExcludedPaths, logger);
    resources.addAll(cu.getResources());

    // gwt-dev-*.jar
    gwtIncludedPaths =
        new HashSet<String>(Arrays.asList(new String[] {
            "com/google/gwt/core/client", "com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang",
            "com/google/gwt/lang",}));
    cu =
        new JarFileResources(new JarFile[] {gwtDevJar}, gwtIncludedPaths, new HashSet<String>(),
            logger);
    resources.addAll(cu.getResources());
    return resources;
  }

  /**
   * This is a hack to make the ApiChecker able to find the javax.validation
   * sources, which we include through an external jar file.
   */
  private Set<Resource> getJavaxValidationCompilationUnits(TreeLogger logger)
      throws UnableToCompleteException, NotFoundException, IOException {
    Set<Resource> resources = new HashSet<Resource>();
    if (extraSourceJars != null) {
      Resources extra = new JarFileResources(
          extraSourceJars,
          Collections.singleton(""), 
          new HashSet<String>(Arrays.asList(
              "javax/validation/Configuration.java",
              "javax/validation/MessageInterpolator.java",
              "javax/validation/Validation.java",
              "javax/validation/ValidatorContext.java",
              "javax/validation/ValidatorFactory.java",
              "javax/validation/ValidationProviderResolver.java",
              "javax/validation/bootstrap/GenericBootstrap.java",
              "javax/validation/bootstrap/ProviderSpecificBootstrap.java",
              "javax/validation/constraints/Pattern.java",
              "javax/validation/spi/BootstrapState.java",
              "javax/validation/spi/ConfigurationState.java",
              "javax/validation/spi/ValidationProvider.java")), 
          logger);
      Set<Resource> loaded = extra.getResources();
      System.out.println("Found " + loaded.size() + " new resources");
      resources.addAll(loaded);
    }
    return resources;
  }

  /*
   * excludedPackages is used in only one place: to determine whether some class
   * is an api class or not
   */
  private Set<String> getSetOfExcludedPackages(Properties config) {
    String allExcludedPackages = config.getProperty("excludedPackages");
    if (allExcludedPackages == null) {
      allExcludedPackages = "";
    }
    String excludedPackagesArray[] = allExcludedPackages.split(":");
    return new HashSet<String>(Arrays.asList(excludedPackagesArray));
  }

  /**
   * Each whiteList element is an {@link ApiElement} and
   * {@link ApiChange.Status} separated by space. For example,
   * "java.util.ArrayList::size() MISSING". The {@code ApiElement} is
   * represented as the string obtained by invoking the getRelativeSignature()
   * method on {@link ApiElement}.
   */
  private Set<String> readWhiteListFromFile(FileReader fr) throws IOException {
    Set<String> hashSet = new HashSet<String>();
    BufferedReader br = new BufferedReader(fr);
    String str = null;
    while ((str = br.readLine()) != null) {
      str = str.trim();
      // ignore comments
      if (str.startsWith("#")) {
        continue;
      }
      String splits[] = str.split(" ");
      if (splits.length > 1 && ApiChange.contains(splits[1])) {
        String identifier = splits[0] + ApiDiffGenerator.DELIMITER + splits[1];
        hashSet.add(identifier.trim());
      }
    }
    return hashSet;
  }

}
