// Copyright 2017 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.common.options;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import com.google.devtools.common.options.Converters.AssignmentConverter;
import com.google.devtools.common.options.Converters.IntegerConverter;
import com.google.devtools.common.options.Converters.StringConverter;
import com.google.devtools.common.options.OptionDefinition.NotAnOptionException;
import com.google.devtools.common.options.OptionsParser.ConstructionException;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;

/** Tests for {@link OptionDefinition}. */
@RunWith(JUnit4.class)
public class OptionDefinitionTest {

  /** Dummy options class, to test various expected failures of the OptionDefinition. */
  public static class BrokenOptions extends OptionsBase {
    public String notAnOption;

    @Option(
      name = "assignments",
      defaultValue = "foo is not an assignment",
      converter = AssignmentConverter.class,
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = OptionEffectTag.NO_OP
    )
    public Map.Entry<String, String> assignments;
  }

  @Test
  public void optionConverterCannotParseDefaultValue() throws Exception {
    OptionDefinition optionDef =
        OptionDefinition.extractOptionDefinition(BrokenOptions.class.getField("assignments"));
    ConstructionException e =
        assertThrows(
            "Incorrect default should have caused getDefaultValue to fail.",
            ConstructionException.class,
            () -> optionDef.getDefaultValue());
    assertThat(e)
        .hasMessageThat()
        .contains(
            "OptionsParsingException while retrieving the default value for assignments: "
                + "Variable definitions must be in the form of a 'name=value' assignment");
  }

  @Test
  public void optionDefinitionRejectsNonOptions() throws Exception {
    NotAnOptionException e =
        assertThrows(
            "notAnOption isn't an Option, and shouldn't be accepted as one.",
            NotAnOptionException.class,
            () ->
                OptionDefinition.extractOptionDefinition(
                    BrokenOptions.class.getField("notAnOption")));
    assertThat(e)
        .hasMessageThat()
        .contains(
            "The field notAnOption does not have the right annotation to be considered an "
                + "option.");
  }

  /**
   * Dummy options class with valid options for testing the memoization of converters and default
   * values.
   */
  public static class ValidOptionUsingDefaultConverterForMocking extends OptionsBase {
    @Option(
      name = "foo",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.NO_OP},
      defaultValue = "42"
    )
    public int foo;

    @Option(
      name = "bar",
      converter = StringConverter.class,
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.NO_OP},
      defaultValue = "strings"
    )
    public String bar;
  }

  /**
   * Test that the converter and option default values are only computed once and then are obtained
   * from the stored values, in the case where a default converter is used.
   */
  @Test
  public void optionDefinitionMemoizesDefaultConverterValue() throws Exception {
    OptionDefinition optionDefinition =
        OptionDefinition.extractOptionDefinition(
            ValidOptionUsingDefaultConverterForMocking.class.getField("foo"));
    OptionDefinition mockOptionDef = Mockito.spy(optionDefinition);

    // Do a bunch of potentially repeat operations on this option that need to know information
    // about the converter and default value. Also verify that the values are as expected.
    boolean isBoolean = mockOptionDef.usesBooleanValueSyntax();
    assertThat(isBoolean).isFalse();

    Converter<?> converter = mockOptionDef.getConverter();
    assertThat(converter).isInstanceOf(IntegerConverter.class);

    int value = (int) mockOptionDef.getDefaultValue();
    assertThat(value).isEqualTo(42);

    // Expect reference equality, since we didn't recompute the value
    Converter<?> secondConverter = mockOptionDef.getConverter();
    assertThat(secondConverter).isSameInstanceAs(converter);

    mockOptionDef.getDefaultValue();

    // Verify that we didn't re-calculate the converter from the provided class object.
    verify(mockOptionDef, times(1)).getProvidedConverter();
    // The first call to getDefaultValue checks isSpecialNullDefault, which called
    // getUnparsedValueDefault as well, but expect no more calls to it after the initial call.
    verify(mockOptionDef, times(1)).isSpecialNullDefault();
    verify(mockOptionDef, times(2)).getUnparsedDefaultValue();
  }

  /**
   * Test that the converter and option default values are only computed once and then are obtained
   * from the stored values, in the case where a converter was provided.
   */
  @Test
  public void optionDefinitionMemoizesProvidedConverterValue() throws Exception {
    OptionDefinition optionDefinition =
        OptionDefinition.extractOptionDefinition(
            ValidOptionUsingDefaultConverterForMocking.class.getField("bar"));
    OptionDefinition mockOptionDef = Mockito.spy(optionDefinition);

    // Do a bunch of potentially repeat operations on this option that need to know information
    // about the converter and default value. Also verify that the values are as expected.
    boolean isBoolean = mockOptionDef.usesBooleanValueSyntax();
    assertThat(isBoolean).isFalse();

    Converter<?> converter = mockOptionDef.getConverter();
    assertThat(converter).isInstanceOf(StringConverter.class);

    String value = (String) mockOptionDef.getDefaultValue();
    assertThat(value).isEqualTo("strings");

    // Expect reference equality, since we didn't recompute the value
    Converter<?> secondConverter = mockOptionDef.getConverter();
    assertThat(secondConverter).isSameInstanceAs(converter);

    mockOptionDef.getDefaultValue();

    // Verify that we didn't re-calculate the converter from the provided class object.
    verify(mockOptionDef, times(1)).getProvidedConverter();
    // The first call to getDefaultValue checks isSpecialNullDefault, which called
    // getUnparsedValueDefault as well, but expect no more calls to it after the initial call.
    verify(mockOptionDef, times(1)).isSpecialNullDefault();
    verify(mockOptionDef, times(2)).getUnparsedDefaultValue();
  }

  /** Dummy options class, to test defaultValue handling. */
  private static class DefaultValueTestOptions extends OptionsBase {
    @Option(
        name = "null_non_multiple_option",
        defaultValue = "null",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = OptionEffectTag.NO_OP)
    public String nullNonMultipleOption;

    @Option(
        name = "null_multiple_option",
        allowMultiple = true,
        defaultValue = "null",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = OptionEffectTag.NO_OP)
    public List<String> nullMultipleOption;

    @Option(
        name = "empty_string_multiple_option",
        allowMultiple = true,
        defaultValue = "",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = OptionEffectTag.NO_OP)
    public List<String> emptyStringMultipleOption;

    @Option(
        name = "non_empty_string_multiple_option",
        allowMultiple = true,
        defaultValue = "text",
        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
        effectTags = OptionEffectTag.NO_OP)
    public List<String> nonEmptyStringMultipleOption;
  }

  @Test
  public void specialDefaultValueForNonMultipleOptionShouldResultInNull() throws Exception {
    // arrange
    OptionDefinition optionDef =
        OptionDefinition.extractOptionDefinition(
            DefaultValueTestOptions.class.getField("nullNonMultipleOption"));

    // act
    Object result = optionDef.getDefaultValue();

    // assert
    assertThat(result).isNull();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void specialDefaultValueForMultipleOptionShouldResultInEmptyList() throws Exception {
    // arrange
    OptionDefinition optionDef =
        OptionDefinition.extractOptionDefinition(
            DefaultValueTestOptions.class.getField("nullMultipleOption"));

    // act
    List<String> result = (List<String>) optionDef.getDefaultValue();

    // assert
    assertThat(result).isEmpty();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void emptyStringForMultipleOptionShouldResultInEmptyList() throws Exception {
    // arrange
    OptionDefinition optionDef =
        OptionDefinition.extractOptionDefinition(
            DefaultValueTestOptions.class.getField("emptyStringMultipleOption"));

    // act
    List<String> result = (List<String>) optionDef.getDefaultValue();

    // assert
    assertThat(result).isEmpty();
  }

  @Test
  @SuppressWarnings("unchecked")
  public void nonEmptyStringForMultipleOptionShouldResultInEmptyList() throws Exception {
    // arrange
    OptionDefinition optionDef =
        OptionDefinition.extractOptionDefinition(
            DefaultValueTestOptions.class.getField("nonEmptyStringMultipleOption"));

    // act
    List<String> result = (List<String>) optionDef.getDefaultValue();

    // assert
    // TODO(b/138573276): this is a legacy behavior - assert the value is actually converted
    assertThat(result).isEmpty();
  }
}
