// 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 com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.common.collect.ImmutableMap;
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.events.Location;
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.syntax.Type;
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

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

  private ConfiguredRuleClassProvider provider = TestRuleClassProvider.getRuleClassProvider();
  private RuleFactory ruleFactory = new RuleFactory(provider, AttributeContainer::new);

  public static final Location LOCATION_42 = Location.fromFileAndOffsets(null, 42, 42);

  @Test
  public void testCreateRule() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg/BUILD");
    Package.Builder pkgBuilder =
        packageFactory
            .newPackageBuilder(PackageIdentifier.createInMainRepo("mypkg"), "TESTING")
            .setFilename(RootedPath.toRootedPath(root, 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),
            new Reporter(new EventBus()),
            /*ast=*/ null,
            LOCATION_42,
            /*env=*/ null,
            new AttributeContainer(ruleClass));

    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.parseAbsolute("//mypkg:foo", ImmutableMap.of()));
    assertThat(rule.getName()).isEqualTo("foo");

    assertThat(rule.getRuleClass()).isEqualTo("cc_library");
    assertThat(rule.getTargetKind()).isEqualTo("cc_library rule");
    assertThat(rule.getLocation().getStartOffset()).isEqualTo(42);
    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");

    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),
            new Reporter(new EventBus()),
            /*ast=*/ null,
            Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
            /*env=*/ null,
            new AttributeContainer(ruleClass));
    assertThat(rule.containsErrors()).isFalse();
  }

  @Test
  public void testWorkspaceRuleFailsInBuildFile() throws Exception {
    Path myPkgPath = scratch.resolve("/workspace/mypkg/BUILD");
    Package.Builder pkgBuilder =
        packageFactory
            .newPackageBuilder(PackageIdentifier.createInMainRepo("mypkg"), "TESTING")
            .setFilename(RootedPath.toRootedPath(root, 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),
                    new Reporter(new EventBus()),
                    /*ast=*/ null,
                    LOCATION_42,
                    /*env=*/ null,
                    new AttributeContainer(ruleClass)));
    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 =
        packageFactory
            .newPackageBuilder(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER, "TESTING")
            .setFilename(RootedPath.toRootedPath(root, 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),
                    new Reporter(new EventBus()),
                    /*ast=*/ null,
                    Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
                    /*env=*/ null,
                    new AttributeContainer(ruleClass)));
    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 =
        packageFactory
            .newPackageBuilder(PackageIdentifier.createInMainRepo("mypkg"), "TESTING")
            .setFilename(RootedPath.toRootedPath(root, 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),
                    new Reporter(new EventBus()),
                    /*ast=*/ null,
                    Location.fromFileAndOffsets(myPkgPath.asFragment(), 42, 42),
                    /*env=*/ null,
                    new AttributeContainer(ruleClass)));
    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 =
        packageFactory
            .newPackageBuilder(PackageIdentifier.createInMainRepo("mypkg"), "TESTING")
            .setFilename(RootedPath.toRootedPath(root, 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),
              new AttributeContainer(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);
      }
    }
  }
}
