// 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 org.junit.Assert.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();
  }
}
