/*
 * 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.dev.resource.impl;

import org.apache.tools.ant.types.ZipScanner;

import java.util.regex.Pattern;

/**
 * A singleton class that provides blazingly fast implementation of the default
 * excludes of Ant's {@link org.apache.tools.ant.DirectoryScanner}, assuming
 * case-sensitiveness.
 *
 * TODO: this class needs to be revisited, when Gwt's Ant is upgraded.
 *
 * Currently, we do not go to ant if (a) the filterList is empty, or (b) the
 * filterList has "common" patterns. Exception: When path ends in '/', we defer
 * to ant.
 *
 * TODO: This code could be made more general and cleaner by removing the
 * dependency on Ant completely. All ant patterns could be compiled into
 * reg-exps. That could also make the code faster. Plus, at several places,
 * Ant's documentation seems to be incomplete. Instead, perhaps, we should
 * specify our own rules for writing patterns.
 */
public class DefaultFilters {

  /**
   * Constants to represent the type of files that will be filtered.
   */
  public static enum FilterFileType {
    RESOURCE_FILES(null), //
    JAVA_FILES(".java"), //
    CLASS_FILES(".class");

    private final String suffix;

    /* used when defaultExcludes is false */
    private final ResourceFilter justThisFileTypeFilter = new ResourceFilter() {
      @Override
      public boolean allows(String path) {
        return defaultAntIncludes.allows(path) && matches(path);
      }
    };

    private final ResourceFilter defaultFilter = new ResourceFilter() {

      @Override
      public boolean allows(String path) {
        return getFileTypeFilter().allows(path)
        && !isDefaultExcluded(path);
      }
    };

    private FilterFileType(String suffix) {
      this.suffix = suffix;
    }

    public ResourceFilter getDefaultFilter() {
      return defaultFilter;
    }

    /* used when defaultExcludes is false */
    public ResourceFilter getFileTypeFilter() {
      return justThisFileTypeFilter;
    }

    public String getSuffix() {
      return suffix;
    }

    public boolean matches(String path) {
      if (suffix == null) {
        return true;
      }
      return path.endsWith(suffix);
    }
  }

  // \w (word character), ., $, /, -, *, ~, #, %
  private static final Pattern antPattern = Pattern.compile("^[\\w\\.\\$/\\-\\*~#%]*$");

  // accepts all but paths starting with '/'. Default include list is '**'
  private static final ResourceFilter defaultAntIncludes = new ResourceFilter() {
    @Override
    public boolean allows(String path) {
      return path.charAt(0) != '/';
    }
  };

  /**
   * @return <code>true</code> if given path should be excluded from resources.
   */
  private static boolean isDefaultExcluded(String path) {
    // CVS
    if (path.endsWith("/CVS") || path.contains("/CVS/") || path.startsWith("CVS/")
        || path.endsWith("/.cvsignore")) {
      return true;
    }
    // Subversion
    if (path.endsWith("/.svn") || path.contains("/.svn/") || path.startsWith(".svn/")
        || path.endsWith("/.svnignore")) {
      return true;
    }
    // Git
    if (path.endsWith("/.git") || path.contains("/.git/") || path.startsWith(".git/")
        || path.endsWith("/.gitignore")) {
      return true;
    }
    // SCCS
    if (path.endsWith("/SCCS") || path.contains("/SCCS/")) {
      return true;
    }
    // Visual SourceSafe
    if (path.endsWith("/vssver.scc")) {
      return true;
    }
    // Mac
    if (path.endsWith("/.DS_Store")) {
      return true;
    }
    return false;
  }

  /**
   * Returns a pattern string that can be passed in Java Pattern.compile(..).
   * For spec, see <a href="http://www.jajakarta.org/ant/ant-1.6.1/docs/ja/manual/api/org/apache/tools/ant/DirectoryScanner.html"
   * >DirectoryScanner</a> From the spec: There is a special case regarding the
   * use of File.separators at the beginning of the pattern and the string to
   * match: When a pattern starts with a File.separator, the string to match
   * must also start with a File.separator. When a pattern does not start with a
   * File.separator, the string to match may not start with a File.separator.
   *
   * </p>
   *
   * TODO: This method could accept all ant patterns, but then all characters
   * that have a special meaning in Java's regular expression would need to be
   * escaped.
   *
   * @param antPatternString the ant pattern String.
   * @return a pattern string that can be passed in Java's Pattern.compile(..),
   *         null if cannot process the pattern.
   */
  static String getPatternFromAntPattern(String antPatternString) {
    if (!antPattern.matcher(antPatternString).matches()) {
      return null;
    }
    // do not handle patterns that have ***
    if (antPatternString.indexOf("***") != -1) {
      return null;
    }
    if (antPatternString.endsWith("/")) {
      /*
       * From the DirectoryScanner.html spec: When a pattern ends with a '/' or
       * '\', "**" is appended. if ant pattern = testing/, path = testing/foo,
       * result = true.
       */
      antPatternString = antPatternString + "**";
    }
    StringBuilder sb = new StringBuilder();
    int length = antPatternString.length();
    for (int i = 0; i < length; i++) {
      char c = antPatternString.charAt(i);
      switch (c) {
        case '.':
          sb.append("\\.");
          break;
        case '$':
          sb.append("\\$");
          break;
        case '/':
          // convert /** to (/[^/]*)* except when / is the first char.
          if (i != 0 && i + 2 < length && antPatternString.charAt(i + 1) == '*'
              && antPatternString.charAt(i + 2) == '*') {
            sb.append("(/[^/]*)*");
            i += 2; // handled 2 more chars than usual
          } else {
            sb.append(c);
          }
          break;
        case '*':
          // ** to .*
          if (i + 1 < length && antPatternString.charAt(i + 1) == '*') {
            if (i + 2 < length && antPatternString.charAt(i + 2) == '/') {
              if (i == 0) {
                /*
                 * When a pattern does not start with a File.separator, the
                 * string to match may not start with a File.separator.
                 */
                sb.append("([^/]+/)*");
              } else {
                // convert **/ to ([^/]*/)*
                sb.append("([^/]*/)*");
              }
              i += 2;
            } else {
              if (i == 0) {
                /*
                 * When a pattern does not start with a File.separator, the
                 * string to match may not start with a File.separator.
                 */
                sb.append("([^/].*)*");
              } else {
                sb.append(".*");
              }
              i++;
            }
          } else {
            sb.append("[^/]*");
          }
          break;
        default:
          sb.append(c);
          break;
      }
    }
    return sb.toString();
  }

  static ZipScanner getScanner(String[] includeList, String[] excludeList,
      String[] skipList, boolean defaultExcludes, boolean caseSensitive) {
    /*
     * Hijack Ant's ZipScanner to handle inclusions/exclusions exactly as Ant
     * does. We're only using its pattern-matching capabilities; the code path
     * I'm using never tries to hit the filesystem in Ant 1.6.5.
     */
    ZipScanner scanner = new ZipScanner();
    if (includeList.length > 0) {
      scanner.setIncludes(includeList);
    }
    if (excludeList.length > 0 || skipList.length > 0) {
      String[] excludeOrSkip = concatenate(excludeList, skipList);
      scanner.setExcludes(excludeOrSkip);
    }
    if (defaultExcludes) {
      scanner.addDefaultExcludes();
    }
    scanner.setCaseSensitive(caseSensitive);
    scanner.init();

    return scanner;
  }

  private static String[] concatenate(String[] array1, String[] array2) {
    String[] answer = new String[array1.length + array2.length];
    int i = 0;
    for (String entry : array1) {
      answer[i++] = entry;
    }
    for (String entry : array2) {
      answer[i++] = entry;
    }
    return answer;
  }

  private static Pattern getPatternFromStrings(String... patterns) {
    StringBuilder entirePattern = new StringBuilder("^");
    int length = patterns.length;
    int count = 0;
    for (String pattern : patterns) {
      entirePattern.append("(" + pattern + ")");
      if (count < length - 1) {
        entirePattern.append("|");
      }
      count++;
    }
    entirePattern.append("$");
    return Pattern.compile(entirePattern.toString());
  }

  private final ResourceFilter rejectAll = new ResourceFilter() {
    @Override
    public boolean allows(String path) {
      return false;
    }
  };

  public ResourceFilter customClassFilesFilter(String includeList[],
      String excludeList[], String skipList[], boolean defaultExcludes,
      boolean caseSensitive) {
    return getCustomFilter(includeList, excludeList, skipList, defaultExcludes,
        caseSensitive, FilterFileType.CLASS_FILES);
  }

  public ResourceFilter customJavaFilter(String includeList[],
      String excludeList[], String skipList[], boolean defaultExcludes,
      boolean caseSensitive) {
    return getCustomFilter(includeList, excludeList, skipList, defaultExcludes,
        caseSensitive, FilterFileType.JAVA_FILES);
  }

  public ResourceFilter customResourceFilter(String includeList[],
      String excludeList[], String[] skipList, boolean defaultExcludes,
      boolean caseSensitive) {
    return getCustomFilter(includeList, excludeList, skipList, defaultExcludes,
        caseSensitive, FilterFileType.RESOURCE_FILES);
  }

  /**
   * Return a customResourceFiter that handles all the argument. If unable to
   * create a customResourceFilter that handles the arguments, catchAll is used
   * as the final ResourceFilter.
   */
  ResourceFilter customFilterWithCatchAll(final String includeList[],
      final String excludeList[], final String skipList[],
      final boolean defaultExcludes, final ResourceFilter catchAll,
      final FilterFileType filterFileType) {

    assert includeList.length > 0 || excludeList.length > 0
        || skipList.length > 0;

    final ResourceFilter includeFilter = getIncludesFilterPart(includeList);
    final ResourceFilter excludeFilter = getExcludesFilterPart(concatenate(
        excludeList, skipList));

    if (includeFilter == null || excludeFilter == null) {
      return catchAll;
    }
    // another common-case
    ResourceFilter filter = new ResourceFilter() {
      @Override
      public boolean allows(String path) {
        // do not handle the case when pattern ends in '/'
        if (path.endsWith("/")) {
          return catchAll.allows(path);
        }
        return isPathAllowedByDefaults(path, defaultExcludes, filterFileType)
            && includeFilter.allows(path) && !excludeFilter.allows(path);
      }

      private boolean isPathAllowedByDefaults(String path,
          boolean defaultExcludes, FilterFileType filterFileType) {
        boolean fileTypeMatch = filterFileType.matches(path);
        if (!fileTypeMatch) {
          return false;
        }
        if (defaultExcludes) {
          return !isDefaultExcluded(path);
        }
        return true;
      }
    };
    return filter;
  }

  ResourceFilter getCustomFilter(final String includeList[],
      final String excludeList[], final String skipList[],
      final boolean defaultExcludes, final boolean caseSensitive,
      final FilterFileType filterFileType) {
    if (includeList.length == 0 && excludeList.length == 0
        && skipList.length == 0 && caseSensitive) {
      // optimize for the common case.
      return getMatchingDefaultFilter(defaultExcludes, filterFileType);
    }

    // don't create a catchAll in default cases
    ResourceFilter catchAll = new ResourceFilter() {
      ZipScanner scanner = getScanner(includeList, excludeList, skipList,
          defaultExcludes, caseSensitive);

      @Override
      public boolean allows(String path) {
        return filterFileType.matches(path) && scanner.match(path);
      }
    };

    // for now, don't handle case sensitivity
    if (!caseSensitive) {
      return catchAll;
    }
    return customFilterWithCatchAll(includeList, excludeList, skipList,
        defaultExcludes, catchAll, filterFileType);
  }

  ResourceFilter getExcludesFilterPart(final String list[]) {
    return getFilterPart(list, false);
  }

  ResourceFilter getIncludesFilterPart(final String list[]) {
    return getFilterPart(list, true);
  }

  /**
   * @param list patterns to add to the filter.
   * @param isInclude Only used if the array is empty. If <code>true</code>
   *          treat this as an include. Otherwise, assume this is an excludes
   *          filter and exclude all files.
   * @return
   */
  private ResourceFilter getFilterPart(final String list[],
      final boolean isInclude) {
    if (list.length == 0) {
      return isInclude ? defaultAntIncludes : rejectAll;
    }

    String patternStrings[] = new String[list.length];
    int count = 0;
    for (String antPatternString : list) {
      String patternString = getPatternFromAntPattern(antPatternString);
      if (patternString == null) {
        return null;
      }
      patternStrings[count++] = patternString;
    }

    final Pattern pattern = getPatternFromStrings(patternStrings);
    return new ResourceFilter() {
      @Override
      public boolean allows(String path) {
        return pattern.matcher(path).matches();
      }
    };
  }

  /**
   * Obtain the appropriate resourceFilter based on defaultExcludes and isJava
   * values. Assumptions: caseSensitive = true,and the includesList and
   * excludesList are empty
   */
  private ResourceFilter getMatchingDefaultFilter(boolean defaultExcludes,
      FilterFileType filterFileType) {
    if (defaultExcludes) {
      return filterFileType.getDefaultFilter();
    }
    return filterFileType.getFileTypeFilter();
  }
}
