// Copyright 2015 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.skyframe;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.cmdline.TargetPattern;
import com.google.devtools.build.lib.cmdline.TargetPattern.Type;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternSkyKeyOrException;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.AbstractSkyKey;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.List;

/**
 * The value returned by {@link PrepareDepsOfPatternFunction}. Because that function is
 * invoked only for its side effect (i.e. ensuring the graph contains targets matching the
 * pattern and its transitive dependencies), this value carries no information.
 *
 * <p>Because the returned value is always equal to objects that share its type, this value and the
 * {@link PrepareDepsOfPatternFunction} which computes it are incompatible with change pruning. It
 * should only be requested by consumers who do not require reevaluation when
 * {@link PrepareDepsOfPatternFunction} is reevaluated. Safe consumers include, e.g., top-level
 * consumers, and other functions which invoke {@link PrepareDepsOfPatternFunction} solely for its
 * side-effects.
 */
public class PrepareDepsOfPatternValue implements SkyValue {
  // Note that this value does not guarantee singleton-like reference equality because we use Java
  // deserialization. Java deserialization can create other instances.
  @AutoCodec
  public static final PrepareDepsOfPatternValue INSTANCE = new PrepareDepsOfPatternValue();

  private PrepareDepsOfPatternValue() {
  }

  @Override
  public boolean equals(Object o) {
    return o instanceof PrepareDepsOfPatternValue;
  }

  @Override
  public int hashCode() {
    return 42;
  }

  /**
   * Returns a {@link PrepareDepsOfPatternSkyKeysAndExceptions}, containing {@link
   * PrepareDepsOfPatternSkyKeyValue} and {@link PrepareDepsOfPatternSkyKeyException} instances that
   * have {@link TargetPatternKey} arguments. Negative target patterns of type other than {@link
   * Type#TARGETS_BELOW_DIRECTORY} are not permitted. If a provided pattern fails to parse or is
   * negative but not a {@link Type#TARGETS_BELOW_DIRECTORY}, there will be a corresponding {@link
   * PrepareDepsOfPatternSkyKeyException} in the iterable returned by {@link
   * PrepareDepsOfPatternSkyKeysAndExceptions#getExceptions} whose {@link
   * PrepareDepsOfPatternSkyKeyException#getException} and {@link
   * PrepareDepsOfPatternSkyKeyException#getOriginalPattern} methods return the {@link
   * TargetParsingException} and original pattern, respectively.
   *
   * <p>There may be fewer returned elements in {@link
   * PrepareDepsOfPatternSkyKeysAndExceptions#getValues} than patterns provided as input. This
   * function will combine negative {@link Type#TARGETS_BELOW_DIRECTORY} patterns with preceding
   * patterns to return an iterable of SkyKeys that avoids loading excluded directories during
   * evaluation.
   *
   * @param patterns The list of patterns, e.g. [//foo/..., -//foo/biz/...]. If a pattern's first
   *     character is "-", it is treated as a negative pattern.
   * @param offset The offset to apply to relative target patterns.
   */
  @ThreadSafe
  public static PrepareDepsOfPatternSkyKeysAndExceptions keys(
      List<String> patterns, PathFragment offset) {
    ImmutableList.Builder<PrepareDepsOfPatternSkyKeyValue> resultValuesBuilder =
        ImmutableList.builder();
    ImmutableList.Builder<PrepareDepsOfPatternSkyKeyException> resultExceptionsBuilder =
        ImmutableList.builder();
    Iterable<TargetPatternSkyKeyOrException> keysMaybe =
        TargetPatternValue.keys(patterns, FilteringPolicies.NO_FILTER, offset);
    ImmutableList.Builder<TargetPatternKey> targetPatternKeysBuilder = ImmutableList.builder();
    for (TargetPatternSkyKeyOrException keyMaybe : keysMaybe) {
      try {
        SkyKey key = keyMaybe.getSkyKey();
        targetPatternKeysBuilder.add((TargetPatternKey) key.argument());
      } catch (TargetParsingException e) {
        resultExceptionsBuilder.add(
            new PrepareDepsOfPatternSkyKeyException(e, keyMaybe.getOriginalPattern()));
      }
    }
    // This code path is evaluated only for query universe preloading, and the quadratic cost of
    // the code below (i.e. for each pattern, consider each later pattern as a candidate for
    // subdirectory exclusion) is only acceptable because all the use cases for query universe
    // preloading involve short (<10 items) pattern sequences.
    Iterable<TargetPatternKey> combinedTargetPatternKeys =
        TargetPatternValue.combineTargetsBelowDirectoryWithNegativePatterns(
            targetPatternKeysBuilder.build(), /*excludeSingleTargets=*/ false);
    for (TargetPatternKey targetPatternKey : combinedTargetPatternKeys) {
      if (targetPatternKey.isNegative()
          && !targetPatternKey
              .getParsedPattern()
              .getType()
              .equals(TargetPattern.Type.TARGETS_BELOW_DIRECTORY)) {
        resultExceptionsBuilder.add(
            new PrepareDepsOfPatternSkyKeyException(
                new TargetParsingException(
                    "Negative target patterns of types other than \"targets below directory\""
                        + " are not permitted.",
                    TargetPatterns.Code.NEGATIVE_TARGET_PATTERN_NOT_ALLOWED),
                targetPatternKey.toString()));
      } else {
        resultValuesBuilder.add(new PrepareDepsOfPatternSkyKeyValue(targetPatternKey));
      }
    }
    return new PrepareDepsOfPatternSkyKeysAndExceptions(
        resultValuesBuilder.build(), resultExceptionsBuilder.build());
  }

  /**
   * A pair of {@link Iterable<PrepareDepsOfPatternSkyKeyValue>} and
   * {@link Iterable<PrepareDepsOfPatternSkyKeyException>}.
   */
  public static class PrepareDepsOfPatternSkyKeysAndExceptions {
    private final Iterable<PrepareDepsOfPatternSkyKeyValue> values;
    private final Iterable<PrepareDepsOfPatternSkyKeyException> exceptions;

    public PrepareDepsOfPatternSkyKeysAndExceptions(
        Iterable<PrepareDepsOfPatternSkyKeyValue> values,
        Iterable<PrepareDepsOfPatternSkyKeyException> exceptions) {
      this.values = values;
      this.exceptions = exceptions;
    }

    public Iterable<PrepareDepsOfPatternSkyKeyValue> getValues() {
      return values;
    }

    public Iterable<PrepareDepsOfPatternSkyKeyException> getExceptions() {
      return exceptions;
    }
  }

  /** Represents a {@link TargetParsingException} when parsing a target pattern string. */
  public static class PrepareDepsOfPatternSkyKeyException {

    private final TargetParsingException exception;
    private final String originalPattern;

    public PrepareDepsOfPatternSkyKeyException(TargetParsingException exception,
        String originalPattern) {
      this.exception = exception;
      this.originalPattern = originalPattern;
    }

    public TargetParsingException getException() {
      return exception;
    }

    public String getOriginalPattern() {
      return originalPattern;
    }
  }

  /**
   * Represents the successful parsing of a target pattern string into a {@link TargetPatternKey}.
   */
  public static class PrepareDepsOfPatternSkyKeyValue {

    private final TargetPatternKey targetPatternKey;

    PrepareDepsOfPatternSkyKeyValue(TargetPatternKey targetPatternKey) {
      this.targetPatternKey = targetPatternKey;
    }

    public Key getSkyKey() {
      return Key.create(targetPatternKey);
    }

    @AutoCodec
    static class Key extends AbstractSkyKey<TargetPatternKey> {
      private static final Interner<Key> interner = BlazeInterners.newWeakInterner();

      private Key(TargetPatternKey arg) {
        super(arg);
      }

      @AutoCodec.VisibleForSerialization
      @AutoCodec.Instantiator
      static Key create(TargetPatternKey arg) {
        return interner.intern(new Key(arg));
      }

      TargetPatternKey getTargetPatternKey() {
        return arg;
      }

      @Override
      public SkyFunctionName functionName() {
        return SkyFunctions.PREPARE_DEPS_OF_PATTERN;
      }
    }
  }
}
