// 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.combineNegativeTargetsBelowDirectoryPatterns(
            targetPatternKeysBuilder.build());
    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;
      }
    }
  }
}
