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

import com.google.common.base.CharMatcher;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * Helper class encapsulating string scanning state used during "heuristic"
 * expansion of labels embedded within rules.
 */
public final class LabelExpander {
  /**
   * An exception that is thrown when a label is expanded to zero or multiple
   * files during expansion.
   */
  public static class NotUniqueExpansionException extends Exception {
    public NotUniqueExpansionException(int sizeOfResultSet, String labelText) {
      super("heuristic label expansion found '" + labelText + "', which expands to "
          + sizeOfResultSet + " files"
          + (sizeOfResultSet > 1
              ? ", please use $(locations " + labelText + ") instead"
              : ""));
    }
  }

  // This is a utility class, no need to instantiate.
  private LabelExpander() {}

  /**
   * CharMatcher to determine if a given character is valid for labels.
   *
   * <p>The Build Concept Reference additionally allows '=' and ',' to appear in labels,
   * but for the purposes of the heuristic, this function does not, as it would cause
   * "--foo=:rule1,:rule2" to scan as a single possible label, instead of three
   * ("--foo", ":rule1", ":rule2").
   */
  private static final CharMatcher LABEL_CHAR_MATCHER =
      CharMatcher.inRange('a', 'z')
      .or(CharMatcher.inRange('A', 'Z'))
      .or(CharMatcher.inRange('0', '9'))
      .or(CharMatcher.anyOf(":/_.-+" + PathFragment.SEPARATOR_CHAR))
      .precomputed();

  /**
   * Expands all references to labels embedded within a string using the
   * provided expansion mapping from labels to artifacts.
   *
   * <p>Since this pass is heuristic, references to non-existent labels (such
   * as arbitrary words) or invalid labels are simply ignored and are unchanged
   * in the output. However, if the heuristic discovers a label, which
   * identifies an existing target producing zero or multiple files, an error
   * is reported.
   *
   * @param expression the expression to expand.
   * @param labelMap the mapping from labels to artifacts, whose relative path
   *     is to be used as the expansion.
   * @param labelResolver the {@code Label} that can resolve label strings
   *     to {@code Label} objects. The resolved label is either relative to
   *     {@code labelResolver} or is a global label (i.e. starts with "//").
   * @return the expansion of the string.
   * @throws NotUniqueExpansionException if a label that is present in the
   *     mapping expands to zero or multiple files.
   */
  public static <T extends Iterable<Artifact>> String expand(@Nullable String expression,
      Map<Label, T> labelMap, Label labelResolver) throws NotUniqueExpansionException {
    if (Strings.isNullOrEmpty(expression)) {
      return "";
    }
    Preconditions.checkNotNull(labelMap);
    Preconditions.checkNotNull(labelResolver);

    int offset = 0;
    StringBuilder result = new StringBuilder();
    while (offset < expression.length()) {
      String labelText = scanLabel(expression, offset);
      if (labelText != null) {
        offset += labelText.length();
        result.append(tryResolvingLabelTextToArtifactPath(labelText, labelMap, labelResolver));
      } else {
        result.append(expression.charAt(offset));
        offset++;
      }
    }
    return result.toString();
  }

  /**
   * Tries resolving a label text to a full label for the associated {@code
   * Artifact}, using the provided mapping.
   *
   * <p>The method succeeds if the label text can be resolved to a {@code
   * Label} object, which is present in the {@code labelMap} and maps to
   * exactly one {@code Artifact}.
   *
   * @param labelText the text to resolve.
   * @param labelMap the mapping from labels to artifacts, whose relative path
   *     is to be used as the expansion.
   * @param labelResolver the {@code Label} that can resolve label strings
   *     to {@code Label} objects. The resolved label is either relative to
   *     {@code labelResolver} or is a global label (i.e. starts with "//").
   * @return an absolute label to an {@code Artifact} if the resolving was
   *     successful or the original label text.
   * @throws NotUniqueExpansionException if a label that is present in the
   *     mapping expands to zero or multiple files.
   */
  private static <T extends Iterable<Artifact>> String tryResolvingLabelTextToArtifactPath(
      String labelText, Map<Label, T> labelMap, Label labelResolver)
      throws NotUniqueExpansionException {
    Label resolvedLabel = resolveLabelText(labelText, labelResolver);
    if (resolvedLabel != null) {
      Iterable<Artifact> artifacts = labelMap.get(resolvedLabel);
      if (artifacts != null) { // resolvedLabel identifies an existing target
        List<String> locations = new ArrayList<>();
        Artifact.addExecPaths(artifacts, locations);
        int resultSetSize = locations.size();
        if (resultSetSize == 1) {
          return Iterables.getOnlyElement(locations); // success!
        } else {
          throw new NotUniqueExpansionException(resultSetSize, labelText);
        }
      }
    }
    return labelText;
  }

  /**
   * Resolves a string to a label text. Uses {@code labelResolver} to do so.
   * The result is either relative to {@code labelResolver} or is an absolute
   * label. In case of an invalid label text, the return value is null.
   */
  private static Label resolveLabelText(String labelText, Label labelResolver) {
    try {
      return labelResolver.getRelative(labelText);
    } catch (LabelSyntaxException e) {
      // It's a heuristic, so quietly ignore "errors". Because Label.getRelative never
      // returns null, we can use null to indicate an error.
      return null;
    }
  }

  /**
   * Scans the argument string from a given start position until the name of a
   * potential label has been consumed, then returns the label text. If
   * the expression contains no possible label starting at the start position,
   * the return value is null.
   */
  private static String scanLabel(String expression, int start) {
    int offset = start;
    while (offset < expression.length() && LABEL_CHAR_MATCHER.matches(expression.charAt(offset))) {
      ++offset;
    }
    if (offset > start) {
      return expression.substring(start, offset);
    } else {
      return null;
    }
  }
}
