// Copyright 2006 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 org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import net.starlark.java.eval.StarlarkInt;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.Tuple;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test of type-conversions using Type.
 */
@RunWith(JUnit4.class)
public class TypeTest {

  private Label currentRule;

  @Before
  public final void setCurrentRule() throws Exception  {
    this.currentRule = Label.parseAbsolute("//quux:baz", ImmutableMap.of());
  }

  @Test
  public void testInteger() throws Exception {
    Object x = StarlarkInt.of(3);
    assertThat(Type.INTEGER.convert(x, null)).isEqualTo(x);
    assertThat(collectLabels(Type.INTEGER, x)).isEmpty();

    // INTEGER rule attributes must be in signed 32-bit value range.
    // (If we ever relax this, we'll need to audit every place that
    // converts an attribute to an int using toIntUnchecked, since
    // that operation might then fail, and extend the Package
    // serialization protocol to support bigint.)
    StarlarkInt big = StarlarkInt.of(111111111);
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> Type.INTEGER.convert(StarlarkInt.multiply(big, big), "param"));
    assertThat(e)
        .hasMessageThat()
        .contains("for param, got 12345678987654321, want value in signed 32-bit range");

    // Ensure that the range of INTEGER.concat is int32.
    assertThat(Type.INTEGER.concat(Arrays.asList(StarlarkInt.of(0x7fffffff), StarlarkInt.of(1))))
        .isEqualTo(StarlarkInt.of(-0x80000000));
  }

  @Test
  public void testNonInteger() throws Exception {
    Type.ConversionException e =
        assertThrows(Type.ConversionException.class, () -> Type.INTEGER.convert("foo", null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'int', but got \"foo\" (string)");
  }

  // Ensure that types are reported correctly.
  @Test
  public void testTypeErrorMessage() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> Type.STRING_LIST.convert("[(1,2), 3, 4]", "myexpr", null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'list(string)' for myexpr, "
                + "but got \"[(1,2), 3, 4]\" (string)");
  }

  @Test
  public void testString() throws Exception {
    Object s = "foo";
    assertThat(Type.STRING.convert(s, null)).isEqualTo(s);
    assertThat(collectLabels(Type.STRING, s)).isEmpty();
  }

  @Test
  public void testNonString() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> Type.STRING.convert(StarlarkInt.of(3), null));
    assertThat(e).hasMessageThat().isEqualTo("expected value of type 'string', but got 3 (int)");
  }

  @Test
  public void testBoolean() throws Exception {
    Object myTrue = true;
    Object myFalse = false;
    assertThat(Type.BOOLEAN.convert(StarlarkInt.of(1), null)).isEqualTo(Boolean.TRUE);
    assertThat(Type.BOOLEAN.convert(StarlarkInt.of(0), null)).isEqualTo(Boolean.FALSE);
    assertThat(Type.BOOLEAN.convert(true, null)).isTrue();
    assertThat(Type.BOOLEAN.convert(myTrue, null)).isTrue();
    assertThat(Type.BOOLEAN.convert(false, null)).isFalse();
    assertThat(Type.BOOLEAN.convert(myFalse, null)).isFalse();
    assertThat(collectLabels(Type.BOOLEAN, myTrue)).isEmpty();
  }

  @Test
  public void testNonBoolean() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> Type.BOOLEAN.convert("unexpected", null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'int', but got \"unexpected\" (string)");
    // Integers other than [0, 1] should fail.
    e =
        assertThrows(
            Type.ConversionException.class, () -> Type.BOOLEAN.convert(StarlarkInt.of(2), null));
    assertThat(e).hasMessageThat().isEqualTo("boolean is not one of [0, 1]");
    e =
        assertThrows(
            Type.ConversionException.class, () -> Type.BOOLEAN.convert(StarlarkInt.of(-1), null));
    assertThat(e).hasMessageThat().isEqualTo("boolean is not one of [0, 1]");
  }

  @Test
  public void testTriState() throws Exception {
    assertThat(BuildType.TRISTATE.convert(StarlarkInt.of(1), null)).isEqualTo(TriState.YES);
    assertThat(BuildType.TRISTATE.convert(StarlarkInt.of(0), null)).isEqualTo(TriState.NO);
    assertThat(BuildType.TRISTATE.convert(StarlarkInt.of(-1), null)).isEqualTo(TriState.AUTO);
    assertThat(BuildType.TRISTATE.convert(TriState.YES, null)).isEqualTo(TriState.YES);
    assertThat(BuildType.TRISTATE.convert(TriState.NO, null)).isEqualTo(TriState.NO);
    assertThat(BuildType.TRISTATE.convert(TriState.AUTO, null)).isEqualTo(TriState.AUTO);
    assertThat(collectLabels(BuildType.TRISTATE, TriState.YES)).isEmpty();

    // deprecated:
    assertThat(BuildType.TRISTATE.convert(true, null)).isEqualTo(TriState.YES);
    assertThat(BuildType.TRISTATE.convert(false, null)).isEqualTo(TriState.NO);
  }

  @Test
  public void testTriStateDoesNotAcceptArbitraryIntegers() throws Exception {
    for (Integer i : Lists.newArrayList(2, 3, -5, -2, 20)) {
      assertThrows(
          Type.ConversionException.class,
          () -> BuildType.TRISTATE.convert(StarlarkInt.of(i), null));
    }
  }

  @Test
  public void testTriStateDoesNotAcceptStrings() throws Exception {
    List<?> listOfCases = Lists.newArrayList("bad", "true", "auto", "false");
    // TODO(adonovan): add booleans true, false to this list; see b/116691720.
    for (Object entry : listOfCases) {
      assertThrows(Type.ConversionException.class, () -> BuildType.TRISTATE.convert(entry, null));
    }
  }

  @Test
  public void testTagConversion() throws Exception {
    assertThat(Type.BOOLEAN.toTagSet(true, "attribute"))
        .containsExactlyElementsIn(Sets.newHashSet("attribute"));
    assertThat(Type.BOOLEAN.toTagSet(false, "attribute"))
        .containsExactlyElementsIn(Sets.newHashSet("noattribute"));

    assertThat(Type.STRING.toTagSet("whiskey", "preferred_cocktail"))
        .containsExactlyElementsIn(Sets.newHashSet("whiskey"));

    assertThat(
            Type.STRING_LIST.toTagSet(
                Lists.newArrayList("cheddar", "ementaler", "gruyere"), "cheeses"))
        .containsExactlyElementsIn(Sets.newHashSet("cheddar", "ementaler", "gruyere"));
  }

  @Test
  public void testIllegalTagConversionByType() throws Exception {
    assertThrows(
        UnsupportedOperationException.class,
        () -> BuildType.TRISTATE.toTagSet(TriState.AUTO, "some_tristate"));
    assertThrows(
        UnsupportedOperationException.class,
        () -> BuildType.LICENSE.toTagSet(License.NO_LICENSE, "output_license"));
  }

  @Test
  public void testIllegalTagConversIonFromNullOnSupportedType() {
    assertThrows(IllegalStateException.class, () -> Type.BOOLEAN.toTagSet(null, "a_boolean"));
  }

  @Test
  public void testLabel() throws Exception {
    Label label = Label.parseAbsolute("//foo:bar", ImmutableMap.of());
    assertThat(BuildType.LABEL.convert("//foo:bar", null, currentRule)).isEqualTo(label);
    assertThat(collectLabels(BuildType.LABEL, label)).containsExactly(label);
  }

  @Test
  public void testNodepLabel() throws Exception {
    Label label = Label.parseAbsolute("//foo:bar", ImmutableMap.of());
    assertThat(BuildType.NODEP_LABEL.convert("//foo:bar", null, currentRule)).isEqualTo(label);
    assertThat(collectLabels(BuildType.NODEP_LABEL, label)).containsExactly(label);
  }

  @Test
  public void testRelativeLabel() throws Exception {
    assertThat(BuildType.LABEL.convert(":wiz", null, currentRule))
        .isEqualTo(Label.parseAbsolute("//quux:wiz", ImmutableMap.of()));
    assertThat(BuildType.LABEL.convert("wiz", null, currentRule))
        .isEqualTo(Label.parseAbsolute("//quux:wiz", ImmutableMap.of()));
    assertThrows(Type.ConversionException.class, () -> BuildType.LABEL.convert("wiz", null));
  }

  @Test
  public void testInvalidLabel() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> BuildType.LABEL.convert("not//a label", null, currentRule));
    MoreAsserts.assertContainsWordsWithQuotes(e.getMessage(), "not//a label");
  }

  @Test
  public void testNonLabel() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> BuildType.LABEL.convert(StarlarkInt.of(3), null));
    assertThat(e).hasMessageThat().isEqualTo("expected value of type 'string', but got 3 (int)");
  }

  @Test
  public void testStringList() throws Exception {
    Object input = Arrays.asList("foo", "bar", "wiz");
    List<String> converted =
        Type.STRING_LIST.convert(input, null);
    assertThat(converted).isEqualTo(input);
    assertThat(converted).isNotSameInstanceAs(input);
    assertThat(collectLabels(Type.STRING_LIST, input)).isEmpty();
  }

  @Test
  public void testStringDict() throws Exception {
    Object input = ImmutableMap.of("foo", "bar", "wiz", "bang");
    Map<String, String> converted = Type.STRING_DICT.convert(input, null);
    assertThat(converted).isEqualTo(input);
    assertThat(converted).isNotSameInstanceAs(input);
    assertThat(collectLabels(Type.STRING_DICT, converted)).isEmpty();
  }

  @Test
  public void testStringDictBadElements() throws Exception {
    Object input = ImmutableMap.of("foo", StarlarkList.of(null, "bar", "baz"), "wiz", "bang");
    Type.ConversionException e =
        assertThrows(Type.ConversionException.class, () -> Type.STRING_DICT.convert(input, null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'string' for dict value element, "
                + "but got [\"bar\", \"baz\"] (list)");
  }

  @Test
  public void testNonStringList() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> Type.STRING_LIST.convert(StarlarkInt.of(3), "blah"));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'list(string)' for blah, but got 3 (int)");
  }

  @Test
  public void testStringListBadElements() throws Exception {
    Object input = Arrays.<Object>asList("foo", "bar", StarlarkInt.of(1));
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> Type.STRING_LIST.convert(input, "argument quux"));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'string' for element 2 of argument quux, but got 1 (int)");
  }

  @Test
  public void testListDepsetConversion() throws Exception {
    Object input =
        Depset.of(
            Depset.ElementType.STRING, NestedSetBuilder.create(Order.STABLE_ORDER, "a", "b", "c"));
    Type.STRING_LIST.convert(input, null);
  }

  @Test
  public void testLabelList() throws Exception {
    Object input = Arrays.asList("//foo:bar", ":wiz");
    List<Label> converted = BuildType.LABEL_LIST.convert(input, null, currentRule);
    List<Label> expected =
        Arrays.asList(
            Label.parseAbsolute("//foo:bar", ImmutableMap.of()),
            Label.parseAbsolute("//quux:wiz", ImmutableMap.of()));
    assertThat(converted).isEqualTo(expected);
    assertThat(converted).isNotSameInstanceAs(expected);
    assertThat(collectLabels(BuildType.LABEL_LIST, converted)).containsExactlyElementsIn(expected);
  }

  @Test
  public void testNonLabelList() throws Exception {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> BuildType.LABEL_LIST.convert(StarlarkInt.of(3), "foo", currentRule));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'list(label)' for foo, but got 3 (int)");
  }

  @Test
  public void testLabelListBadElements() throws Exception {
    Object list = Arrays.<Object>asList("//foo:bar", StarlarkInt.of(2), "foo");
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> BuildType.LABEL_LIST.convert(list, null, currentRule));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'string' for element 1 of null, but got 2 (int)");
  }

  @Test
  public void testLabelListSyntaxError() throws Exception {
    Object list = Arrays.<Object>asList("//foo:bar/..", "foo");
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> BuildType.LABEL_LIST.convert(list, "myexpr", currentRule));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "invalid label '//foo:bar/..' in element 0 of myexpr: "
                + "invalid target name 'bar/..': "
                + "target names may not contain up-level references '..'");
  }

  @Test
  public void testStringListDict() throws Exception {
    Object input =
        ImmutableMap.of("foo", Arrays.asList("foo", "bar"), "wiz", Arrays.asList("bang"));
    Map<String, List<String>> converted =
        Type.STRING_LIST_DICT.convert(input, null, currentRule);
    Map<?, ?> expected =
        ImmutableMap.of(
            "foo", Arrays.asList("foo", "bar"),
            "wiz", Arrays.asList("bang"));
    assertThat(converted).isEqualTo(expected);
    assertThat(converted).isNotSameInstanceAs(expected);
    assertThat(collectLabels(Type.STRING_LIST_DICT, converted)).isEmpty();
  }

  @Test
  public void testStringListDictBadFirstElement() throws Exception {
    Object input =
        ImmutableMap.of(
            StarlarkInt.of(2), Arrays.asList("foo", "bar"), "wiz", Arrays.asList("bang"));
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> Type.STRING_LIST_DICT.convert(input, null, currentRule));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo("expected value of type 'string' for dict key element, but got 2 (int)");
  }

  @Test
  public void testStringListDictBadSecondElement() throws Exception {
    Object input = ImmutableMap.of("foo", "bar", "wiz", Arrays.asList("bang"));
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class,
            () -> Type.STRING_LIST_DICT.convert(input, null, currentRule));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'list(string)' for dict value element, "
                + "but got \"bar\" (string)");
  }

  @Test
  public void testStringListDictBadElements1() throws Exception {
    Object input = ImmutableMap.of(Tuple.of("foo"), Tuple.of("bang"), "wiz", Tuple.of("bang"));
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> Type.STRING_LIST_DICT.convert(input, null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'string' for dict key element, but got "
                + "(\"foo\",) (tuple)");
  }

  @Test
  public void testStringDictThrowsConversionException() {
    Type.ConversionException e =
        assertThrows(
            Type.ConversionException.class, () -> Type.STRING_DICT.convert("some string", null));
    assertThat(e)
        .hasMessageThat()
        .isEqualTo(
            "expected value of type 'dict(string, string)', but got \"some string\" (string)");
  }

  private static <T> ImmutableList<Label> collectLabels(Type<T> type, Object value) {
    ImmutableList.Builder<Label> result = ImmutableList.builder();
    type.visitLabels((label, dummy) -> result.add(label), type.cast(value), /*context=*/ null);
    return result.build();
  }
}
