/*
 * 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.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 org.apache.tools.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 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 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 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();
      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());
      }
      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));
        newApi = new ApiContainer(
            checker.configProperties.getProperty("name_new"), resources,
            excludedPackages, logger);
        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));
        existingApi = new ApiContainer(
            checker.configProperties.getProperty("name_old"), resources,
            excludedPackages, logger);
        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 getPurpose() {
        return "Prints all api";
      }

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

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

    });

    // 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 the filesystem trees to be included.\n");
    sb.append("excludeFiles     a colon-separated lists of ant patterns to exclude");

    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"}));
    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/Validation.java",
              "javax/validation/constraints/Pattern.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;
  }

}
