// 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.syntax;

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.List;
import java.util.stream.Stream;
import javax.annotation.Nullable;

/**
 * Either the arguments to a glob call (the include and exclude lists) or the
 * contents of a fixed list that was appended to a list of glob results.
 * (The latter need to be stored by {@link GlobList} in order to fully
 * reproduce the inputs that created the output list.)
 *
 * <p>For example, the expression
 * <code>glob(['*.java']) + ['x.properties']</code>
 * will result in two GlobCriteria: one has include = ['*.java'], glob = true
 * and the other, include = ['x.properties'], glob = false.
 */
public class GlobCriteria {

  /**
   * A list of names or patterns that are included by this glob. They should
   * consist of characters that are valid in labels in the BUILD language.
   */
  private final ImmutableList<String> include;

  /**
   * A list of names or patterns that are excluded by this glob. They should
   * consist of characters that are valid in labels in the BUILD language.
   */
  private final ImmutableList<String> exclude;

  /** True if the includes list was passed to glob(), false if not. */
  private final boolean glob;

  /**
   * Parses criteria from its {@link #toExpression} form.
   * Package-private for use by tests and GlobList.
   * @throws IllegalArgumentException if the expression cannot be parsed
   */
  public static GlobCriteria parse(String text) {
    if (text.startsWith("glob([") && text.endsWith("])")) {
      int excludeIndex = text.indexOf("], exclude=[");
      if (excludeIndex == -1) {
        String listText = text.substring(6, text.length() - 2);
        return new GlobCriteria(parseList(listText), ImmutableList.of(), true);
      } else {
        String listText = text.substring(6, excludeIndex);
        String excludeText = text.substring(excludeIndex + 12, text.length() - 2);
        return new GlobCriteria(parseList(listText), parseList(excludeText), true);
      }
    } else if (text.startsWith("[") && text.endsWith("]")) {
      String listText = text.substring(1, text.length() - 1);
      return new GlobCriteria(parseList(listText), ImmutableList.of(), false);
    } else {
      throw new IllegalArgumentException(
          "unrecognized format (not from toExpression?): " + text);
    }
  }

  /**
   * Constructs a copy of a given glob critera object, with additional exclude patterns added.
   *
   * @param base a glob criteria object to copy. Must be an actual glob
   * @param excludes a list of pattern strings indicating new excludes to provide
   * @return a new glob criteria object which contains the same parameters as {@code base}, with
   *   the additional patterns in {@code excludes} added.
   * @throws IllegalArgumentException if {@code base} is not a glob
   */
  public static GlobCriteria createWithAdditionalExcludes(GlobCriteria base,
      List<String> excludes) {
    Preconditions.checkArgument(base.isGlob());
    return fromGlobCall(
        base.include,
        Stream.concat(base.exclude.stream(), excludes.stream()).collect(toImmutableList()));
  }

  /**
   * Constructs a copy of a fixed list, converted to Strings.
   */
  public static GlobCriteria fromList(Iterable<?> list) {
    Iterable<String> strings = Iterables.transform(list, Functions.toStringFunction());
    return new GlobCriteria(ImmutableList.copyOf(strings), ImmutableList.of(), false);
  }

  /**
   * Constructs a glob call with include and exclude list.
   *
   * @param include list of included patterns
   * @param exclude list of excluded patterns
   */
  public static GlobCriteria fromGlobCall(
      ImmutableList<String> include, ImmutableList<String> exclude) {
    return new GlobCriteria(include, exclude, true);
  }

  /**
   * Constructs a glob call with include and exclude list.
   */
  private GlobCriteria(ImmutableList<String> include, ImmutableList<String> exclude, boolean glob) {
    this.include = include;
    this.exclude = exclude;
    this.glob = glob;
  }

  /**
   * Returns the patterns that were included in this {@code glob()} call.
   */
  public ImmutableList<String> getIncludePatterns() {
    return include;
  }

  /**
   * Returns the patterns that were excluded in this {@code glob()} call.
   */
  public ImmutableList<String> getExcludePatterns() {
    return exclude;
  }

  /**
   * Returns true if the include list was passed to {@code glob()}, false
   * if it was a fixed list. If this returns false, the exclude list will
   * always be empty.
   */
  public boolean isGlob() {
    return glob;
  }

  /**
   * Returns a String that represents this glob as a BUILD expression.
   * For example, <code>glob(['abc', 'def'], exclude=['uvw', 'xyz'])</code>
   * or <code>['foo', 'bar', 'baz']</code>.
   */
  public String toExpression() {
    StringBuilder sb = new StringBuilder();
    if (glob) {
      sb.append("glob(");
    }
    sb.append('[');
    appendList(sb, include);
    if (!exclude.isEmpty()) {
      sb.append("], exclude=[");
      appendList(sb, exclude);
    }
    sb.append(']');
    if (glob) {
      sb.append(')');
    }
    return sb.toString();
  }

  @Override
  public String toString() {
    return toExpression();
  }

  /**
   * Takes a list of Strings, quotes them in single quotes, and appends them to
   * a StringBuilder separated by a comma and space. This can be parsed back
   * out by {@link #parseList}.
   */
  private static void appendList(StringBuilder sb, List<String> list) {
    boolean first = true;
    for (String content : list) {
      if (!first) {
        sb.append(", ");
      }
      sb.append('\'').append(content).append('\'');
      first = false;
    }
  }

  /**
   * Takes a String in the format created by {@link #appendList} and returns
   * the original Strings. A null String (which may be returned when Pattern
   * does not find a match) or the String "" (which will be captured in "[]")
   * will result in an empty list.
   */
  private static ImmutableList<String> parseList(@Nullable String text) {
    if (text == null) {
      return ImmutableList.of();
    }
    Iterable<String> split = Splitter.on(", ").split(text);
    ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
    for (String element : split) {
      if (!element.isEmpty()) {
        if ((element.length() < 2) || !element.startsWith("'") || !element.endsWith("'")) {
          throw new IllegalArgumentException("expected a filename or pattern in quotes: " + text);
        }
        listBuilder.add(element.substring(1, element.length() - 1));
      }
    }
    return listBuilder.build();
  }
}
