// 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.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
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.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

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

  private final LabelConverter labelConverter =
      new LabelConverter(
          PackageIdentifier.createInMainRepo("quux"), RepositoryMapping.ALWAYS_FALLBACK);

  @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"));
    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.parseCanonical("//foo:bar");
    assertThat(BuildType.LABEL.convert("//foo:bar", null, labelConverter)).isEqualTo(label);
    assertThat(collectLabels(BuildType.LABEL, label)).containsExactly(label);
  }

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

  @Test
  public void testRelativeLabel() throws Exception {
    assertThat(BuildType.LABEL.convert(":wiz", null, labelConverter))
        .isEqualTo(Label.parseCanonical("//quux:wiz"));
    assertThat(BuildType.LABEL.convert("wiz", null, labelConverter))
        .isEqualTo(Label.parseCanonical("//quux:wiz"));
    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, labelConverter));
    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, labelConverter);
    List<Label> expected =
        Arrays.asList(Label.parseCanonical("//foo:bar"), Label.parseCanonical("//quux:wiz"));
    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", labelConverter));
    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, labelConverter));
    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", labelConverter));
    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, labelConverter);
    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, labelConverter));
    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, labelConverter));
    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();
  }
}
