// 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.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.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, String 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."), 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;
      }
    }
  }
}
