// 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.base.Predicate;
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.AttributeMap;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
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.TestsInSuiteValue.TestsInSuiteKey;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Pair;
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.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * TestsInSuiteFunction takes a single test_suite target and expands all of the tests it contains,
 * possibly recursively.
 */
// TODO(ulfjack): What about test_suite rules that include each other.
final class TestsInSuiteFunction implements SkyFunction {
  @Override
  public SkyValue compute(SkyKey key, Environment env) throws InterruptedException {
    TestsInSuiteKey expansion = (TestsInSuiteKey) key.argument();
    SkyKey packageKey = PackageValue.key(expansion.getTestSuiteLabel().getPackageIdentifier());
    PackageValue pkg = (PackageValue) env.getValue(packageKey);
    if (env.valuesMissing()) {
      return null;
    }
    Rule testSuite = pkg.getPackage().getRule(expansion.getTestSuiteLabel().getName());
    ResolvedTargets<Target> result = computeTestsInSuite(env, testSuite, expansion.isStrict());
    if (env.valuesMissing()) {
      return null;
    }
    return new TestsInSuiteValue(result);
  }

  /**
   * Populates 'result' with all the tests associated with the specified 'testSuite'. Throws an
   * exception if any target is missing.
   *
   * <p>CAUTION! Keep this logic consistent with {@code TestSuite}!
   */
  private static ResolvedTargets<Target> computeTestsInSuite(
      Environment env, Rule testSuite, boolean strict) throws InterruptedException {
    ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
    List<Target> testsAndSuites = new ArrayList<>();
    // Note that testsAndSuites can contain input file targets; the test_suite rule does not
    // restrict the set of targets that can appear in tests or suites.
    builder.mergeError(getPrerequisites(env, testSuite, "tests", testsAndSuites));

    // 1. Add all tests
    for (Target test : testsAndSuites) {
      if (TargetUtils.isTestRule(test)) {
        builder.add(test);
      } else if (strict && !TargetUtils.isTestSuiteRule(test)) {
        // 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(testSuite.getLocation(),
            "in test_suite rule '" + testSuite.getLabel()
            + "': expecting a test or a test_suite rule but '" + test.getLabel()
            + "' is not one."));
        builder.setError();
      }
    }

    // 2. Add implicit dependencies on tests in same package, if any.
    List<Target> implicitTests = new ArrayList<>();
    builder.mergeError(getPrerequisites(env, testSuite, "$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)) {
        builder.add(target);
      }
    }

    // 3. Filter based on tags, size, env.
    filterTests(testSuite, builder);

    // 4. Expand all suites recursively.
    for (Target suite : testsAndSuites) {
      if (TargetUtils.isTestSuiteRule(suite)) {
        TestsInSuiteValue value =
            (TestsInSuiteValue) env.getValue(TestsInSuiteValue.key(suite, strict));
        if (value == null) {
          continue;
        }
        builder.merge(value.getTargets());
      }
    }

    return builder.build();
  }

  /**
   * Adds the set of targets found in the attribute named {@code attrName}, which must be of label
   * list type, of the {@code test_suite} rule named {@code testSuite}. 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 testSuite, String attrName, List<Target> targets)
      throws InterruptedException {
    List<Label> labels =
        NonconfigurableAttributeMapper.of(testSuite).get(attrName, BuildType.LABEL_LIST);
    Set<PackageIdentifier> pkgIdentifiers = new LinkedHashSet<>();
    for (Label label : labels) {
      pkgIdentifiers.add(label.getPackageIdentifier());
    }
    Map<SkyKey, ValueOrException<BuildFileNotFoundException>> packages = env.getValuesOrThrow(
        PackageValue.keys(pkgIdentifiers), BuildFileNotFoundException.class);
    if (env.valuesMissing()) {
      return false;
    }
    boolean hasError = false;
    Map<PackageIdentifier, Package> packageMap = new HashMap<>();
    for (Map.Entry<SkyKey, ValueOrException<BuildFileNotFoundException>> entry :
        packages.entrySet()) {
      try {
        packageMap.put(
            (PackageIdentifier) entry.getKey().argument(),
            ((PackageValue) entry.getValue().get()).getPackage());
      } catch (BuildFileNotFoundException e) {
        env.getListener().handle(Event.error(e.getMessage()));
        hasError = true;
      }
    }

    for (Label label : labels) {
      Package pkg = packageMap.get(label.getPackageIdentifier());
      if (pkg == null) {
        continue;
      }
      try {
        targets.add(pkg.getTarget(label.getName()));
      } catch (NoSuchTargetException e) {
        env.getListener().handle(Event.error(e.getMessage()));
        hasError = true;
      }
    }
    return hasError;
  }

  /**
   * Filters 'tests' (by mutation) according to the 'tags' attribute, specifically those that
   * match ALL of the tags in tagsAttribute.
   */
  private static void filterTests(Rule testSuite, ResolvedTargets.Builder<Target> tests) {
    List<String> tagsAttribute =
        NonconfigurableAttributeMapper.of(testSuite).get("tags", Type.STRING_LIST);
    // Split the tags list into positive and negative tags.
    Pair<Collection<String>, Collection<String>> tagLists =
        TestTargetUtils.sortTagsBySense(tagsAttribute);
    final Collection<String> positiveTags = tagLists.first;
    final Collection<String> negativeTags = tagLists.second;

    tests.filter(new Predicate<Target>() {
      @Override
      public boolean apply(@Nullable Target input) {
        Rule test = (Rule) input;
        AttributeMap nonConfigurableAttributes = NonconfigurableAttributeMapper.of(test);
        List<String> testTags =
            new ArrayList<>(nonConfigurableAttributes.get("tags", Type.STRING_LIST));
        testTags.add(nonConfigurableAttributes.get("size", Type.STRING));
        return includeTest(testTags, positiveTags, negativeTags);
      }
    });
  }

  /**
   * Decides whether to include a test in a test_suite or not.
   *
   * @param testTags Collection of all tags exhibited by a given test.
   * @param positiveTags Tags declared by the suite. A Test must match ALL of these.
   * @param negativeTags Tags declared by the suite. A Test must match NONE of these.
   * @return false if the test is to be removed.
   */
  private static boolean includeTest(Collection<String> testTags,
      Collection<String> positiveTags, Collection<String> negativeTags) {
    // Add this test if it matches ALL of the positive tags and NONE of the
    // negative tags in the tags attribute.
    for (String tag : negativeTags) {
      if (testTags.contains(tag)) {
        return false;
      }
    }
    for (String tag : positiveTags) {
      if (!testTags.contains(tag)) {
        return false;
      }
    }
    return true;
  }

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