// 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.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
import static com.google.devtools.build.lib.syntax.Type.INTEGER;
import static com.google.devtools.build.lib.syntax.Type.STRING;
import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
import static org.junit.Assert.fail;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.util.PackageLoadingTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for the {@link RuleClass.Builder}.
 */
@RunWith(JUnit4.class)
public class RuleClassBuilderTest extends PackageLoadingTestCase {
  private static final RuleClass.ConfiguredTargetFactory<Object, Object, Exception>
      DUMMY_CONFIGURED_TARGET_FACTORY =
          new RuleClass.ConfiguredTargetFactory<Object, Object, Exception>() {
            @Override
            public Object create(Object ruleContext)
                throws InterruptedException, RuleErrorException, ActionConflictException {
              throw new IllegalStateException();
            }
          };

  @Test
  public void testRuleClassBuilderBasics() throws Exception {
    RuleClass ruleClassA =
        new RuleClass.Builder("ruleA", RuleClassType.NORMAL, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("srcs", BuildType.LABEL_LIST).legacyAllowAnyFileType())
            .add(attr("tags", STRING_LIST))
            .add(attr("X", com.google.devtools.build.lib.syntax.Type.INTEGER).mandatory())
            .build();

    assertThat(ruleClassA.getName()).isEqualTo("ruleA");
    assertThat(ruleClassA.getAttributeCount()).isEqualTo(3);
    assertThat(ruleClassA.hasBinaryOutput()).isTrue();

    assertThat((int) ruleClassA.getAttributeIndex("srcs")).isEqualTo(0);
    assertThat(ruleClassA.getAttributeByName("srcs")).isEqualTo(ruleClassA.getAttribute(0));

    assertThat((int) ruleClassA.getAttributeIndex("tags")).isEqualTo(1);
    assertThat(ruleClassA.getAttributeByName("tags")).isEqualTo(ruleClassA.getAttribute(1));

    assertThat((int) ruleClassA.getAttributeIndex("X")).isEqualTo(2);
    assertThat(ruleClassA.getAttributeByName("X")).isEqualTo(ruleClassA.getAttribute(2));
  }

  @Test
  public void testRuleClassBuilderTestIsBinary() throws Exception {
    RuleClass ruleClassA =
        new RuleClass.Builder("rule_test", RuleClassType.TEST, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("tags", STRING_LIST))
            .add(attr("size", STRING).value("medium"))
            .add(attr("timeout", STRING))
            .add(attr("flaky", BOOLEAN).value(false))
            .add(attr("shard_count", INTEGER).value(-1))
            .add(attr("local", BOOLEAN))
            .build();
    assertThat(ruleClassA.hasBinaryOutput()).isTrue();
  }

  @Test
  public void testRuleClassBuilderGenruleIsNotBinary() throws Exception {
    RuleClass ruleClassA =
        new RuleClass.Builder("ruleA", RuleClassType.NORMAL, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .setOutputToGenfiles()
            .add(attr("tags", STRING_LIST))
            .build();
    assertThat(ruleClassA.hasBinaryOutput()).isFalse();
  }

  @Test
  public void testRuleClassTestNameValidity() throws Exception {
    try {
      new RuleClass.Builder("ruleA", RuleClassType.TEST, false).build();
      fail();
    } catch (IllegalArgumentException e) {
      // Expected exception.
    }
  }

  @Test
  public void testRuleClassNormalNameValidity() throws Exception {
    try {
      new RuleClass.Builder("ruleA_test", RuleClassType.NORMAL, false).build();
      fail();
    } catch (IllegalArgumentException e) {
      // Expected exception.
    }
  }

  @Test
  public void testDuplicateAttribute() throws Exception {
    RuleClass.Builder builder =
        new RuleClass.Builder("ruleA", RuleClassType.NORMAL, false).add(attr("a", STRING));
    try {
      builder.add(attr("a", STRING));
      fail();
    } catch (IllegalStateException e) {
      // Expected exception.
    }
  }

  @Test
  public void testPropertiesOfAbstractRuleClass() throws Exception {
    try {
      new RuleClass.Builder("$ruleA", RuleClassType.ABSTRACT, false).setOutputToGenfiles();
      fail();
    } catch (IllegalStateException e) {
      // Expected exception.
    }

    try {
      new RuleClass.Builder("$ruleB", RuleClassType.ABSTRACT, false)
          .setImplicitOutputsFunction(null);
      fail();
    } catch (IllegalStateException e) {
      // Expected exception.
    }
  }

  @Test
  public void testDuplicateInheritedAttribute() throws Exception {
    RuleClass a =
        new RuleClass.Builder("ruleA", RuleClassType.NORMAL, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("a", STRING).value("A"))
            .add(attr("tags", STRING_LIST))
            .build();
    RuleClass b =
        new RuleClass.Builder("ruleB", RuleClassType.NORMAL, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("a", STRING).value("B"))
            .add(attr("tags", STRING_LIST))
            .build();
    try {
      // In case of multiple attribute inheritance the attributes must equal
      new RuleClass.Builder("ruleC", RuleClassType.NORMAL, false, a, b).build();
      fail();
    } catch (IllegalArgumentException e) {
      assertThat(e)
          .hasMessageThat()
          .isEqualTo("Attribute a is inherited multiple times in ruleC ruleclass");
    }
  }

  @Test
  public void testRemoveAttribute() throws Exception {
    RuleClass a =
        new RuleClass.Builder("rule", RuleClassType.NORMAL, false)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("a", STRING))
            .add(attr("b", STRING))
            .add(attr("tags", STRING_LIST))
            .build();
    RuleClass.Builder builder =
        new RuleClass.Builder("c", RuleClassType.NORMAL, false, a)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY);
    RuleClass c = builder.removeAttribute("a").add(attr("a", INTEGER)).removeAttribute("b").build();
    assertThat(c.hasAttr("a", STRING)).isFalse();
    assertThat(c.hasAttr("a", INTEGER)).isTrue();
    assertThat(c.hasAttr("b", STRING)).isFalse();

    try {
      builder.removeAttribute("c");
      fail();
    } catch (IllegalStateException e) {
      // Expected exception.
    }
  }

  @Test
  public void testRequiredToolchainsAreInherited() throws Exception {
    Label mockToolchainType = Label.parseAbsoluteUnchecked("//mock_toolchain_type");
    RuleClass parent =
        new RuleClass.Builder("$parent", RuleClassType.ABSTRACT, false)
            .add(attr("tags", STRING_LIST))
            .addRequiredToolchains(ImmutableList.of(mockToolchainType))
            .build();
    RuleClass child =
        new RuleClass.Builder("child", RuleClassType.NORMAL, false, parent)
            .factory(DUMMY_CONFIGURED_TARGET_FACTORY)
            .add(attr("attr", STRING))
            .build();
    assertThat(child.getRequiredToolchains()).contains(mockToolchainType);
  }

  @Test
  public void testBasicRuleNamePredicates() throws Exception {
    Predicate<String> abcdef = nothingBut("abc", "def").asPredicateOfRuleClassName();
    assertThat(abcdef.test("abc")).isTrue();
    assertThat(abcdef.test("def")).isTrue();
    assertThat(abcdef.test("ghi")).isFalse();
  }

  @Test
  public void testTwoRuleNamePredicateFactoriesEquivalent() throws Exception {
    RuleClassNamePredicate a = nothingBut("abc", "def");
    RuleClassNamePredicate b = RuleClassNamePredicate.only(ImmutableList.of("abc", "def"));
    assertThat(a.asPredicateOfRuleClassName()).isEqualTo(b.asPredicateOfRuleClassName());
    assertThat(a.asPredicateOfRuleClass()).isEqualTo(b.asPredicateOfRuleClass());
  }

  @Test
  public void testEverythingButRuleNamePredicates() throws Exception {
    Predicate<String> abcdef = allBut("abc", "def").asPredicateOfRuleClassName();
    assertThat(abcdef.test("abc")).isFalse();
    assertThat(abcdef.test("def")).isFalse();
    assertThat(abcdef.test("ghi")).isTrue();
  }

  @Test
  public void testRuleClassNamePredicateIntersection() {
    // two positives intersect iff they contain any of the same items
    assertThat(nothingBut("abc", "def").consideredOverlapping(nothingBut("abc"))).isTrue();
    assertThat(nothingBut("abc", "def").consideredOverlapping(nothingBut("ghi"))).isFalse();

    // negatives are never considered to overlap...
    assertThat(allBut("abc", "def").consideredOverlapping(allBut("abc", "def"))).isFalse();
    assertThat(allBut("abc", "def").consideredOverlapping(allBut("ghi", "jkl"))).isFalse();

    assertThat(allBut("abc", "def").consideredOverlapping(nothingBut("abc", "def"))).isFalse();
    assertThat(nothingBut("abc", "def").consideredOverlapping(allBut("abc", "def"))).isFalse();

    assertThat(allBut("abc", "def").consideredOverlapping(nothingBut("abc"))).isFalse();
    assertThat(allBut("abc").consideredOverlapping(nothingBut("abc", "def"))).isFalse();
  }

  private RuleClassNamePredicate nothingBut(String... excludedRuleClasses) {
    return RuleClassNamePredicate.only(excludedRuleClasses);
  }

  private RuleClassNamePredicate allBut(String... excludedRuleClasses) {
    return RuleClassNamePredicate.allExcept(excludedRuleClasses);
  }
}
