// 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.ImmutableMap;
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.getRelativeWithRemapping(labelText, ImmutableMap.of());
    } 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;
    }
  }
}
