// 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.ImmutableSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.ResolvedTargets;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.TestTargetUtils;
import com.google.devtools.build.lib.skyframe.TestExpansionValue.TestExpansionKey;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.ValueOrException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * TestExpansionFunction takes a single expandable test target ({@code test_suite} or {@code alias})
 * and expands it recursively.
 */
// TODO(ulfjack): What about test_suite rules that include each other.
final class TestExpansionFunction implements SkyFunction {
  @Override
  public SkyValue compute(SkyKey key, Environment env) throws InterruptedException {
    TestExpansionKey expansion = (TestExpansionKey) key.argument();
    SkyKey packageKey = PackageValue.key(expansion.getLabel().getPackageIdentifier());
    PackageValue pkg = (PackageValue) env.getValue(packageKey);
    if (env.valuesMissing()) {
      return null;
    }
    Rule rule = pkg.getPackage().getRule(expansion.getLabel().getName());
    ResolvedTargets<Label> result = computeExpandedTests(env, rule, expansion.isStrict());
    if (env.valuesMissing()) {
      return null;
    }
    return new TestExpansionValue(result);
  }

  private static Set<Label> toLabels(Set<Target> targets) {
    return targets.stream().map(Target::getLabel).collect(Collectors.toSet());
  }

  /**
   * Populates 'result' with all the tests associated with the specified 'rule'. Throws an exception
   * if any target is missing.
   *
   * <p>CAUTION! Keep this logic consistent with {@code TestSuite}!
   */
  private static ResolvedTargets<Label> computeExpandedTests(
      Environment env, Rule rule, boolean strict) throws InterruptedException {
    Set<Target> result = new HashSet<>();
    boolean hasError = false;

    List<Target> prerequisites = new ArrayList<>();
    if (TargetUtils.isTestSuiteRule(rule)) {
      // Note that prerequisites can contain input file targets; the test_suite rule does not
      // restrict the set of targets that can appear in tests or suites.
      hasError |= getPrerequisites(env, rule, "tests", prerequisites);
    } else if (TargetUtils.isAlias(rule)) {
      hasError |= getPrerequisites(env, rule, "actual", prerequisites);
    }

    // Add all tests
    for (Target test : prerequisites) {
      if (TargetUtils.isTestRule(test)) {
        result.add(test);
      } else if (strict && !TargetUtils.isTestSuiteRule(test) && !TargetUtils.isAlias(rule)) {
        // If strict mode is enabled, then give an error for any non-test, non-test-suite targets.
        // TODO(ulfjack): We need to throw to end the process if we happen to be in --nokeep_going,
        // but we can't know whether or not we are at this point.
        env.getListener()
            .handle(
                Event.error(
                    rule.getLocation(),
                    "in test_suite rule '"
                        + rule.getLabel()
                        + "': expecting a test or a test_suite rule but '"
                        + test.getLabel()
                        + "' is not one."));
        hasError = true;
      }
    }

    if (TargetUtils.isTestSuiteRule(rule)) {
      // Add implicit dependencies on tests in same package, if any.
      List<Target> implicitTests = new ArrayList<>();
      hasError |= getPrerequisites(env, rule, "$implicit_tests", implicitTests);
      for (Target target : implicitTests) {
        // The Package construction of $implicit_tests ensures that this check never fails, but we
        // add it here anyway for compatibility with future code.
        if (TargetUtils.isTestRule(target)) {
          result.add(target);
        }
      }

      // Filter based on tags, size, env.
      TestTargetUtils.filterTests(rule, result);
    }

    // Expand all rules recursively, collecting labels.
    ResolvedTargets.Builder<Label> labelsBuilder = ResolvedTargets.builder();
    // Don't set filtered targets; they would be removed from the containing rule.
    labelsBuilder.merge(new ResolvedTargets<>(toLabels(result), ImmutableSet.of(), hasError));

    for (Target suite : prerequisites) {
      if (TargetUtils.isTestSuiteRule(suite) || TargetUtils.isAlias(suite)) {
        TestExpansionValue value =
            (TestExpansionValue) env.getValue(TestExpansionValue.key(suite, strict));
        if (value == null) {
          continue;
        }
        labelsBuilder.merge(value.getLabels());
      }
    }

    return labelsBuilder.build();
  }

  /**
   * Adds the set of targets found in the attribute named {@code attrName}, which must be of label
   * or label list list type, Returns true if the method found a problem during the lookup process;
   * the actual error message is reported to the environment.
   */
  private static boolean getPrerequisites(
      Environment env, Rule rule, String attrName, List<Target> targets)
      throws InterruptedException {
    AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
    List<Label> labels =
        mapper.visitLabels(mapper.getAttributeDefinition(attrName)).stream()
            .map(e -> e.getLabel())
            .collect(Collectors.toList());

    Set<PackageIdentifier> pkgIdentifiers = new LinkedHashSet<>();

    for (Label label : labels) {
      pkgIdentifiers.add(label.getPackageIdentifier());
    }

    Map<SkyKey, ValueOrException<NoSuchPackageException>> packages =
        env.getValuesOrThrow(PackageValue.keys(pkgIdentifiers), NoSuchPackageException.class);
    if (env.valuesMissing()) {
      return false;
    }

    boolean hasError = false;
    Map<PackageIdentifier, Package> packageMap = new HashMap<>();

    for (Map.Entry<SkyKey, ValueOrException<NoSuchPackageException>> entry : packages.entrySet()) {
      try {
        packageMap.put(
            (PackageIdentifier) entry.getKey().argument(),
            ((PackageValue) entry.getValue().get()).getPackage());
      } catch (NoSuchPackageException e) {
        env.getListener().handle(Event.error(e.getMessage()));
        hasError = true;
      }
    }

    for (Label label : labels) {
      Package pkg = packageMap.get(label.getPackageIdentifier());
      if (pkg == null) {
        continue;
      }
      if (pkg.containsErrors()) {
        hasError = true;
        // Abort the build if --nokeep_going.
        try {
          env.getValueOrThrow(
              PackageErrorFunction.key(label.getPackageIdentifier()),
              BuildFileContainsErrorsException.class);
          return false;
        } catch (BuildFileContainsErrorsException e) {
          // PackageErrorFunction always throws this exception, and this fact is used by Skyframe to
          // abort the build. If we get here, it's either because of error bubbling or because we're
          // in --keep_going mode. In either case, we *should* ignore the exception.
        }
      }
      try {
        targets.add(pkg.getTarget(label.getName()));
      } catch (NoSuchTargetException e) {
        env.getListener().handle(Event.error(e.getMessage()));
        hasError = true;
      }
    }
    return hasError;
  }

  @Nullable
  @Override
  public String extractTag(SkyKey skyKey) {
    return null;
  }
}
