// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.util;

import com.google.common.base.Joiner;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.OptionsParsingException;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Handles options that specify list of included/excluded regex expressions.
 * Validates whether string is included in that filter.
 *
 * String is considered to be included into the filter if it does not match
 * any of the excluded regex expressions and if it matches at least one
 * included regex expression.
 */
@Immutable
public final class RegexFilter implements Serializable {
  private final Pattern inclusionPattern;
  private final Pattern exclusionPattern;
  private final int hashCode;

  /**
   * Converts from a colon-separated list of regex expressions with optional
   * -/+ prefix into the RegexFilter. Colons prefixed with backslash are
   * considered to be part of regex definition and not a delimiter between
   * separate regex expressions.
   *
   * Order of expressions is not important. Empty entries are ignored.
   * '-' marks an excluded expression.
   */
  public static class RegexFilterConverter
      implements Converter<RegexFilter> {

    @Override
    public RegexFilter convert(String input) throws OptionsParsingException {
      List<String> inclusionList = new ArrayList<>();
      List<String> exclusionList = new ArrayList<>();

      for (String piece : input.split("(?<!\\\\),")) { // Split on ',' but not on '\,'
        piece = piece.replace("\\,", ",");
        boolean isExcluded = piece.startsWith("-");
        if (isExcluded || piece.startsWith("+")) {
          piece = piece.substring(1);
        }
        if (piece.length() > 0) {
          (isExcluded ? exclusionList : inclusionList).add(piece);
        }
      }

      try {
        return new RegexFilter(inclusionList, exclusionList);
      } catch (PatternSyntaxException e) {
        throw new OptionsParsingException("Failed to build valid regular expression: "
            + e.getMessage());
      }
    }

    @Override
    public String getTypeDescription() {
      return "a comma-separated list of regex expressions with prefix '-' specifying"
          + " excluded paths";
    }

  }

  /**
   * Creates new RegexFilter using provided inclusion and exclusion path lists.
   */
  public RegexFilter(List<String> inclusions, List<String> exclusions) {
    inclusionPattern = convertRegexListToPattern(inclusions);
    exclusionPattern = convertRegexListToPattern(exclusions);
    hashCode = Objects.hash(inclusions, exclusions);
  }

  /**
   * Converts list of regex expressions into one compiled regex expression.
   */
  private static Pattern convertRegexListToPattern(List<String> regexList) {
    if (regexList.isEmpty()) {
      return null;
    }
    // Wrap each individual regex in the independent group, combine them using '|' and
    // wrap in the non-capturing group.
    return Pattern.compile("(?:(?>" + Joiner.on(")|(?>").join(regexList) + "))");
  }

  /**
   * @return true iff given string is included (it is does not match exclusion
   *         pattern (if any) and matches inclusionPatter (if any).
   */
  public boolean isIncluded(String value) {
    if (exclusionPattern != null && exclusionPattern.matcher(value).find()) {
      return false;
    }
    if (inclusionPattern == null) {
      return true;
    }
    return inclusionPattern.matcher(value).find();
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    if (inclusionPattern != null) {
      builder.append(inclusionPattern.pattern().replace(",", "\\,"));
      if (exclusionPattern != null) {
        builder.append(",");
      }
    }
    if (exclusionPattern != null) {
      builder.append("-");
      builder.append(exclusionPattern.pattern().replace(",", "\\,"));
    }
    return builder.toString();
  }
  
  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (!(other instanceof RegexFilter)) {
      return false;
    }

    RegexFilter otherFilter = (RegexFilter) other; 
    if (this.exclusionPattern == null ^ otherFilter.exclusionPattern == null) {
      return false;
    }
    if (this.inclusionPattern == null ^ otherFilter.inclusionPattern == null) {
      return false;
    }
    if (this.exclusionPattern != null && !this.exclusionPattern.pattern().equals(
        otherFilter.exclusionPattern.pattern())) {
      return false;
    }
    if (this.inclusionPattern != null && !this.inclusionPattern.pattern().equals(
        otherFilter.inclusionPattern.pattern())) {
      return false;
    }
    return true;
  }
  
  @Override
  public int hashCode() {
    return hashCode;
  }
}
