// 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.packages;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.events.Reporter;
import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.RootedPath;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.syntax.Location;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public final class RuleFactoryTest extends PackageLoadingTestCase {

  private ConfiguredRuleClassProvider provider = TestRuleClassProvider.getRuleClassProvider();
  private final RuleFactory ruleFactory = new RuleFactory(provider);

  private static final ImmutableList<StarlarkThread.CallStackEntry> DUMMY_STACK =
      ImmutableList.of(
          new StarlarkThread.CallStackEntry(
              "<toplevel>", Location.fromFileLineColumn("BUILD", 42, 1)),
          new StarlarkThread.CallStackEntry("foo", Location.fromFileLineColumn("foo.bzl", 10, 1)),
          new StarlarkThread.CallStackEntry(
              "myrule", Location.fromFileLineColumn("bar.bzl", 30, 6)));

  private Package.Builder newBuilder(PackageIdentifier id, Path filename) {
    return packageFactory
        .newPackageBuilder(
            id,
            "TESTING",
            Optional.empty(),
            Optional.empty(),
            StarlarkSemantics.DEFAULT,
            RepositoryMapping.ALWAYS_FALLBACK,
            RepositoryMapping.ALWAYS_FALLBACK)
        .setFilename(RootedPath.toRootedPath(root, filename));
  }

  @Test
  public void testCreateRule() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg/BUILD");
    Package.Builder pkgBuilder = newBuilder(PackageIdentifier.createInMainRepo("mypkg"), myPkgPath);

    Map<String, Object> attributeValues = new HashMap<>();
    attributeValues.put("name", "foo");
    attributeValues.put("alwayslink", true);

    RuleClass ruleClass = provider.getRuleClassMap().get("cc_library");
    Rule rule =
        RuleFactory.createAndAddRule(
            pkgBuilder,
            ruleClass,
            new BuildLangTypedAttributeValuesMap(attributeValues),
            true,
            new Reporter(new EventBus()),
            StarlarkSemantics.DEFAULT,
            DUMMY_STACK);

    assertThat(rule.getAssociatedRule()).isSameInstanceAs(rule);

    // pkg.getRules() = [rule]
    Package pkg = pkgBuilder.build();
    assertThat(Sets.newHashSet(pkg.getTargets(Rule.class))).hasSize(1);
    assertThat(pkg.getTargets(Rule.class).iterator().next()).isEqualTo(rule);

    assertThat(pkg.getTarget("foo")).isSameInstanceAs(rule);

    assertThat(rule.getLabel()).isEqualTo(Label.parseCanonical("//mypkg:foo"));
    assertThat(rule.getName()).isEqualTo("foo");

    assertThat(rule.getRuleClass()).isEqualTo("cc_library");
    assertThat(rule.getTargetKind()).isEqualTo("cc_library rule");
    // The rule reports the location of the outermost call (aka generator), in the BUILD file.
    // Thie behavior was added to fix b/23974287, but it loses informtion and is redundant
    // w.r.t. generator_location. A better fix to that issue would be to keep rule.location as
    // the innermost call, and to report the entire call stack at the first error for the rule.
    assertThat(rule.getLocation().file()).isEqualTo("BUILD");
    assertThat(rule.getLocation().line()).isEqualTo(42);
    assertThat(rule.getLocation().column()).isEqualTo(1);
    assertThat(rule.containsErrors()).isFalse();

    // Attr with explicitly-supplied value:
    AttributeMap attributes = RawAttributeMapper.of(rule);
    assertThat(attributes.get("alwayslink", Type.BOOLEAN)).isTrue();
    assertThrows(Exception.class, () -> attributes.get("alwayslink", Type.STRING));
    assertThrows(Exception.class, () -> attributes.get("nosuchattr", Type.STRING));

    // Attrs with default values:
    // cc_library linkstatic default=0 according to build encyc.
    assertThat(attributes.get("linkstatic", Type.BOOLEAN)).isFalse();
    assertThat(attributes.get("testonly", Type.BOOLEAN)).isFalse();
    assertThat(attributes.get("srcs", BuildType.LABEL_LIST)).isEmpty();
  }

  @Test
  public void testCreateWorkspaceRule() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/WORKSPACE");
    Package.Builder pkgBuilder =
        packageFactory.newExternalPackageBuilder(
            RootedPath.toRootedPath(root, myPkgPath),
            "TESTING",
            RepositoryMapping.ALWAYS_FALLBACK,
            StarlarkSemantics.DEFAULT);

    Map<String, Object> attributeValues = new HashMap<>();
    attributeValues.put("name", "foo");
    attributeValues.put("actual", "//foo:bar");

    RuleClass ruleClass = provider.getRuleClassMap().get("bind");
    Rule rule =
        RuleFactory.createAndAddRule(
            pkgBuilder,
            ruleClass,
            new BuildLangTypedAttributeValuesMap(attributeValues),
            true,
            new Reporter(new EventBus()),
            StarlarkSemantics.DEFAULT,
            DUMMY_STACK);
    assertThat(rule.containsErrors()).isFalse();
  }

  @Test
  public void testWorkspaceRuleFailsInBuildFile() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg/BUILD");
    Package.Builder pkgBuilder = newBuilder(PackageIdentifier.createInMainRepo("mypkg"), myPkgPath);

    Map<String, Object> attributeValues = new HashMap<>();
    attributeValues.put("name", "foo");
    attributeValues.put("actual", "//bar:baz");

    RuleClass ruleClass = provider.getRuleClassMap().get("bind");
    RuleFactory.InvalidRuleException e =
        assertThrows(
            RuleFactory.InvalidRuleException.class,
            () ->
                RuleFactory.createAndAddRule(
                    pkgBuilder,
                    ruleClass,
                    new BuildLangTypedAttributeValuesMap(attributeValues),
                    true,
                    new Reporter(new EventBus()),
                    StarlarkSemantics.DEFAULT,
                    DUMMY_STACK));
    assertThat(e).hasMessageThat().contains("must be in the WORKSPACE file");
  }

  @Test
  public void testBuildRuleFailsInWorkspaceFile() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/WORKSPACE");
    Package.Builder pkgBuilder = newBuilder(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER, myPkgPath);

    Map<String, Object> attributeValues = new HashMap<>();
    attributeValues.put("name", "foo");
    attributeValues.put("alwayslink", true);

    RuleClass ruleClass = provider.getRuleClassMap().get("cc_library");
    RuleFactory.InvalidRuleException e =
        assertThrows(
            RuleFactory.InvalidRuleException.class,
            () ->
                RuleFactory.createAndAddRule(
                    pkgBuilder,
                    ruleClass,
                    new BuildLangTypedAttributeValuesMap(attributeValues),
                    true,
                    new Reporter(new EventBus()),
                    StarlarkSemantics.DEFAULT,
                    DUMMY_STACK));
    assertThat(e).hasMessageThat().contains("cannot be in the WORKSPACE file");
  }

  private void assertAttr(RuleClass ruleClass, String attrName, Type<?> type) throws Exception {
    assertWithMessage(
            "Rule class '"
                + ruleClass.getName()
                + "' should have attribute '"
                + attrName
                + "' of type '"
                + type
                + "'")
        .that(ruleClass.hasAttr(attrName, type))
        .isTrue();
  }

  @Test
  public void testOutputFileNotEqualDot() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg");
    Package.Builder pkgBuilder = newBuilder(PackageIdentifier.createInMainRepo("mypkg"), myPkgPath);

    Map<String, Object> attributeValues = new HashMap<>();
    attributeValues.put("outs", Lists.newArrayList("."));
    attributeValues.put("name", "some");
    RuleClass ruleClass = provider.getRuleClassMap().get("genrule");
    RuleFactory.InvalidRuleException e =
        assertThrows(
            RuleFactory.InvalidRuleException.class,
            () ->
                RuleFactory.createAndAddRule(
                    pkgBuilder,
                    ruleClass,
                    new BuildLangTypedAttributeValuesMap(attributeValues),
                    true,
                    new Reporter(new EventBus()),
                    StarlarkSemantics.DEFAULT,
                    DUMMY_STACK));
    assertWithMessage(e.getMessage())
        .that(e.getMessage().contains("output file name can't be equal '.'"))
        .isTrue();
  }

  /** Tests mandatory attribute definitions for test rules. */
  // TODO(ulfjack): Remove this check when we switch over to the builder
  // pattern, which will always guarantee that these attributes are present.
  @Test
  public void testTestRules() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg/BUILD");
    Package pkg = newBuilder(PackageIdentifier.createInMainRepo("mypkg"), myPkgPath).build();

    for (String name : ruleFactory.getRuleClassNames()) {
      // Create rule instance directly so we'll avoid mandatory attribute check yet will be able
      // to use TargetUtils.isTestRule() method to identify test rules.
      RuleClass ruleClass = ruleFactory.getRuleClass(name);
      Rule rule =
          new Rule(
              pkg,
              Label.create(pkg.getPackageIdentifier(), "myrule"),
              ruleClass,
              Location.fromFile(myPkgPath.toString()),
              CallStack.EMPTY,
              AttributeContainer.newMutableInstance(ruleClass));
      if (TargetUtils.isTestRule(rule)) {
        assertAttr(ruleClass, "tags", Type.STRING_LIST);
        assertAttr(ruleClass, "size", Type.STRING);
        assertAttr(ruleClass, "flaky", Type.BOOLEAN);
        assertAttr(ruleClass, "shard_count", Type.INTEGER);
        assertAttr(ruleClass, "local", Type.BOOLEAN);
      }
    }
  }
}
