// Copyright 2014 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.common.options.OptionsParser.newOptionsParser;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.common.options.Converters.CommaSeparatedOptionListConverter;
import com.google.devtools.common.options.OptionsParser.OptionValueDescription;
import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Tests {@link OptionsParser}.
 */
@RunWith(JUnit4.class)
public class OptionsParserTest {

  public static class ExampleFoo extends OptionsBase {

    @Option(name = "foo",
            category = "one",
            defaultValue = "defaultFoo")
    public String foo;

    @Option(name = "bar",
            category = "two",
            defaultValue = "42")
    public int bar;

    @Option(name = "bing",
            category = "one",
            defaultValue = "",
            allowMultiple = true)
    public List<String> bing;

    @Option(name = "bang",
            category = "one",
            defaultValue = "",
            converter = StringConverter.class,
            allowMultiple = true)
    public List<String> bang;

    @Option(name = "nodoc",
        category = "undocumented",
        defaultValue = "",
        allowMultiple = false)
    public String nodoc;
  }

  public static class ExampleBaz extends OptionsBase {

    @Option(name = "baz",
            category = "one",
            defaultValue = "defaultBaz")
    public String baz;
  }

  public static class StringConverter implements Converter<String> {
    @Override
    public String convert(String input) {
      return input;
    }
    @Override
    public String getTypeDescription() {
      return "a string";
    }
  }

  @Test
  public void parseWithMultipleOptionsInterfaces()
      throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    parser.parse("--baz=oops", "--bar", "17");
    ExampleFoo foo = parser.getOptions(ExampleFoo.class);
    assertEquals("defaultFoo", foo.foo);
    assertEquals(17, foo.bar);
    ExampleBaz baz = parser.getOptions(ExampleBaz.class);
    assertEquals("oops", baz.baz);
  }

  @Test
  public void parserWithUnknownOption() {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    try {
      parser.parse("--unknown", "option");
      fail();
    } catch (OptionsParsingException e) {
      assertEquals("--unknown", e.getInvalidArgument());
      assertEquals("Unrecognized option: --unknown", e.getMessage());
    }
    assertEquals(Collections.<String>emptyList(), parser.getResidue());
  }

  @Test
  public void parserWithSingleDashOption() throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    try {
      parser.parse("-baz=oops", "-bar", "17");
      fail();
    } catch (OptionsParsingException expected) {}

    parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    parser.setAllowSingleDashLongOptions(true);
    parser.parse("-baz=oops", "-bar", "17");
    ExampleFoo foo = parser.getOptions(ExampleFoo.class);
    assertEquals("defaultFoo", foo.foo);
    assertEquals(17, foo.bar);
    ExampleBaz baz = parser.getOptions(ExampleBaz.class);
    assertEquals("oops", baz.baz);
  }

  @Test
  public void parsingFailsWithUnknownOptions() {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    List<String> unknownOpts = asList("--unknown", "option", "--more_unknowns");
    try {
      parser.parse(unknownOpts);
      fail();
    } catch (OptionsParsingException e) {
      assertEquals("--unknown", e.getInvalidArgument());
      assertEquals("Unrecognized option: --unknown", e.getMessage());
      assertNotNull(parser.getOptions(ExampleFoo.class));
      assertNotNull(parser.getOptions(ExampleBaz.class));
    }
  }

  @Test
  public void parseKnownAndUnknownOptions() {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    List<String> opts = asList("--bar", "17", "--unknown", "option");
    try {
      parser.parse(opts);
      fail();
    } catch (OptionsParsingException e) {
      assertEquals("--unknown", e.getInvalidArgument());
      assertEquals("Unrecognized option: --unknown", e.getMessage());
      assertNotNull(parser.getOptions(ExampleFoo.class));
      assertNotNull(parser.getOptions(ExampleBaz.class));
    }
  }

  public static class CategoryTest extends OptionsBase {
    @Option(name = "swiss_bank_account_number",
            category = "undocumented", // Not printed in usage messages!
            defaultValue = "123456789")
    public int swissBankAccountNumber;

    @Option(name = "student_bank_account_number",
            category = "one",
            defaultValue = "987654321")
    public int studentBankAccountNumber;
  }

  @Test
  public void getOptionsAndGetResidueWithNoCallToParse() {
    // With no call to parse(), all options are at default values, and there's
    // no reside.
    assertEquals("defaultFoo",
                 newOptionsParser(ExampleFoo.class).
                 getOptions(ExampleFoo.class).foo);
    assertEquals(Collections.<String>emptyList(),
                 newOptionsParser(ExampleFoo.class).getResidue());
  }

  @Test
  public void parserCanBeCalledRepeatedly() throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(ExampleFoo.class);
    parser.parse("--foo", "foo1");
    assertEquals("foo1", parser.getOptions(ExampleFoo.class).foo);
    parser.parse();
    assertEquals("foo1", parser.getOptions(ExampleFoo.class).foo); // no change
    parser.parse("--foo", "foo2");
    assertEquals("foo2", parser.getOptions(ExampleFoo.class).foo); // updated
  }

  @Test
  public void multipleOccuringOption() throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(ExampleFoo.class);
    parser.parse("--bing", "abcdef", "--foo", "foo1", "--bing", "123456" );
    assertThat(parser.getOptions(ExampleFoo.class).bing).containsExactly("abcdef", "123456");
  }

  @Test
  public void multipleOccurringOptionWithConverter() throws OptionsParsingException {
    // --bang is the same as --bing except that it has a "converter" specified.
    // This test also tests option values with embedded commas and spaces.
    OptionsParser parser = newOptionsParser(ExampleFoo.class);
    parser.parse("--bang", "abc,def ghi", "--foo", "foo1", "--bang", "123456" );
    assertThat(parser.getOptions(ExampleFoo.class).bang).containsExactly("abc,def ghi", "123456");
  }

  @Test
  public void parserIgnoresOptionsAfterMinusMinus()
      throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    parser.parse("--foo", "well", "--baz", "here", "--", "--bar", "ignore");
    ExampleFoo foo = parser.getOptions(ExampleFoo.class);
    ExampleBaz baz = parser.getOptions(ExampleBaz.class);
    assertEquals("well", foo.foo);
    assertEquals("here", baz.baz);
    assertEquals(42, foo.bar); // the default!
    assertEquals(asList("--bar", "ignore"), parser.getResidue());
  }

  @Test
  public void parserThrowsExceptionIfResidueIsNotAllowed() {
    OptionsParser parser = newOptionsParser(ExampleFoo.class);
    parser.setAllowResidue(false);
    try {
      parser.parse("residue", "is", "not", "OK");
      fail();
    } catch (OptionsParsingException e) {
      assertEquals("Unrecognized arguments: residue is not OK", e.getMessage());
    }
  }

  @Test
  public void multipleCallsToParse() throws Exception {
    OptionsParser parser = newOptionsParser(ExampleFoo.class);
    parser.setAllowResidue(true);
    parser.parse("--foo", "one", "--bar", "43", "unknown1");
    parser.parse("--foo", "two", "unknown2");
    ExampleFoo foo = parser.getOptions(ExampleFoo.class);
    assertEquals("two", foo.foo); // second call takes precedence
    assertEquals(43, foo.bar);
    assertEquals(Arrays.asList("unknown1", "unknown2"), parser.getResidue());
  }

  // Regression test for a subtle bug!  The toString of each options interface
  // instance was printing out key=value pairs for all flags in the
  // OptionsParser, not just those belonging to the specific interface type.
  @Test
  public void toStringDoesntIncludeFlagsForOtherOptionsInParserInstance()
      throws Exception {
    OptionsParser parser = newOptionsParser(ExampleFoo.class, ExampleBaz.class);
    parser.parse("--foo", "foo", "--bar", "43", "--baz", "baz");

    String fooString = parser.getOptions(ExampleFoo.class).toString();
    if (!fooString.contains("foo=foo") ||
        !fooString.contains("bar=43") ||
        !fooString.contains("ExampleFoo") ||
        fooString.contains("baz=baz")) {
      fail("ExampleFoo.toString() is incorrect: " + fooString);
    }

    String bazString = parser.getOptions(ExampleBaz.class).toString();
    if (!bazString.contains("baz=baz") ||
        !bazString.contains("ExampleBaz") ||
        bazString.contains("foo=foo") ||
        bazString.contains("bar=43")) {
      fail("ExampleBaz.toString() is incorrect: " + bazString);
    }
  }

  // Regression test for another subtle bug!  The toString was printing all the
  // explicitly-specified options, even if they were at their default values,
  // causing toString equivalence to diverge from equals().
  @Test
  public void toStringIsIndependentOfExplicitCommandLineOptions() throws Exception {
    ExampleFoo foo1 = Options.parse(ExampleFoo.class).getOptions();
    ExampleFoo foo2 = Options.parse(ExampleFoo.class, "--bar", "42").getOptions();
    assertEquals(foo1, foo2);
    assertEquals(foo1.toString(), foo2.toString());

    Map<String, Object> expectedMap = new ImmutableMap.Builder<String, Object>().
        put("bing", Collections.emptyList()).
        put("bar", 42).
        put("nodoc", "").
        put("bang", Collections.emptyList()).
        put("foo", "defaultFoo").build();

    assertEquals(expectedMap, foo1.asMap());
    assertEquals(expectedMap, foo2.asMap());
  }

  // Regression test for yet another subtle bug!  The inherited options weren't
  // being printed by toString.  One day, a real rain will come and wash all
  // this scummy code off the streets.
  public static class DerivedBaz extends ExampleBaz {
    @Option(name = "derived", defaultValue = "defaultDerived")
    public String derived;
  }

  @Test
  public void toStringPrintsInheritedOptionsToo_Duh() throws Exception {
    DerivedBaz derivedBaz = Options.parse(DerivedBaz.class).getOptions();
    String derivedBazString = derivedBaz.toString();
    if (!derivedBazString.contains("derived=defaultDerived") ||
        !derivedBazString.contains("baz=defaultBaz")) {
      fail("DerivedBaz.toString() is incorrect: " + derivedBazString);
    }
  }

  // Tests for new default value override mechanism
  public static class CustomOptions extends OptionsBase {
    @Option(name = "simple",
        category = "custom",
        defaultValue = "simple default")
    public String simple;

    @Option(name = "multipart_name",
        category = "custom",
        defaultValue = "multipart default")
    public String multipartName;
  }

  public void assertDefaultStringsForCustomOptions() throws OptionsParsingException {
    CustomOptions options = Options.parse(CustomOptions.class).getOptions();
    assertEquals("simple default", options.simple);
    assertEquals("multipart default", options.multipartName);
  }

  public static class NullTestOptions extends OptionsBase {
    @Option(name = "simple",
            defaultValue = "null")
    public String simple;
  }

  @Test
  public void defaultNullStringGivesNull() throws Exception {
    NullTestOptions options = Options.parse(NullTestOptions.class).getOptions();
    assertNull(options.simple);
  }

  public static class ImplicitDependencyOptions extends OptionsBase {
    @Option(name = "first",
            implicitRequirements = "--second=second",
            defaultValue = "null")
    public String first;

    @Option(name = "second",
        implicitRequirements = "--third=third",
        defaultValue = "null")
    public String second;

    @Option(name = "third",
        defaultValue = "null")
    public String third;
  }

  @Test
  public void implicitDependencyHasImplicitDependency() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ImplicitDependencyOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first=first"));
    assertEquals("first", parser.getOptions(ImplicitDependencyOptions.class).first);
    assertEquals("second", parser.getOptions(ImplicitDependencyOptions.class).second);
    assertEquals("third", parser.getOptions(ImplicitDependencyOptions.class).third);
  }

  public static class BadImplicitDependencyOptions extends OptionsBase {
    @Option(name = "first",
            implicitRequirements = "xxx",
            defaultValue = "null")
    public String first;
  }

  @Test
  public void badImplicitDependency() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(BadImplicitDependencyOptions.class);
    try {
      parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first=first"));
    } catch (AssertionError e) {
      /* Expected error. */
      return;
    }
    fail();
  }

  public static class BadExpansionOptions extends OptionsBase {
    @Option(name = "first",
            expansion = { "xxx" },
            defaultValue = "null")
    public Void first;
  }

  @Test
  public void badExpansionOptions() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(BadExpansionOptions.class);
    try {
      parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first"));
    } catch (AssertionError e) {
      /* Expected error. */
      return;
    }
    fail();
  }

  public static class ExpansionOptions extends OptionsBase {
    @Option(name = "first",
            expansion = { "--second=first" },
            defaultValue = "null")
    public Void first;

    @Option(name = "second",
            defaultValue = "null")
    public String second;
  }

  @Test
  public void overrideExpansionWithExplicit() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ExpansionOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first", "--second=second"));
    ExpansionOptions options = parser.getOptions(ExpansionOptions.class);
    assertEquals("second", options.second);
    assertEquals(0, parser.getWarnings().size());
  }

  @Test
  public void overrideExplicitWithExpansion() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ExpansionOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--second=second", "--first"));
    ExpansionOptions options = parser.getOptions(ExpansionOptions.class);
    assertEquals("first", options.second);
  }

  @Test
  public void overrideWithHigherPriority() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NullTestOptions.class);
    parser.parse(OptionPriority.RC_FILE, null, Arrays.asList("--simple=a"));
    assertEquals("a", parser.getOptions(NullTestOptions.class).simple);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--simple=b"));
    assertEquals("b", parser.getOptions(NullTestOptions.class).simple);
  }

  @Test
  public void overrideWithLowerPriority() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NullTestOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--simple=a"));
    assertEquals("a", parser.getOptions(NullTestOptions.class).simple);
    parser.parse(OptionPriority.RC_FILE, null, Arrays.asList("--simple=b"));
    assertEquals("a", parser.getOptions(NullTestOptions.class).simple);
  }

  @Test
  public void getOptionValueDescriptionWithNonExistingOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NullTestOptions.class);
    try {
      parser.getOptionValueDescription("notexisting");
      fail();
    } catch (IllegalArgumentException e) {
      /* Expected exception. */
    }
  }

  @Test
  public void getOptionValueDescriptionWithoutValue() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NullTestOptions.class);
    assertNull(parser.getOptionValueDescription("simple"));
  }

  @Test
  public void getOptionValueDescriptionWithValue() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NullTestOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, "my description",
        Arrays.asList("--simple=abc"));
    OptionValueDescription result = parser.getOptionValueDescription("simple");
    assertNotNull(result);
    assertEquals("simple", result.getName());
    assertEquals("abc", result.getValue());
    assertEquals(OptionPriority.COMMAND_LINE, result.getPriority());
    assertEquals("my description", result.getSource());
    assertNull(result.getImplicitDependant());
    assertFalse(result.isImplicitDependency());
    assertNull(result.getExpansionParent());
    assertFalse(result.isExpansion());
  }

  public static class ImplicitDependencyWarningOptions extends OptionsBase {
    @Option(name = "first",
            implicitRequirements = "--second=second",
            defaultValue = "null")
    public String first;

    @Option(name = "second",
        defaultValue = "null")
    public String second;

    @Option(name = "third",
            implicitRequirements = "--second=third",
            defaultValue = "null")
    public String third;
  }

  @Test
  public void warningForImplicitOverridingExplicitOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ImplicitDependencyWarningOptions.class);
    parser.parse("--second=second", "--first=first");
    assertThat(parser.getWarnings())
        .containsExactly("Option 'second' is implicitly defined by "
                         + "option 'first'; the implicitly set value overrides the previous one");
  }

  @Test
  public void warningForExplicitOverridingImplicitOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ImplicitDependencyWarningOptions.class);
    parser.parse("--first=first");
    assertThat(parser.getWarnings()).isEmpty();
    parser.parse("--second=second");
    assertThat(parser.getWarnings())
        .containsExactly("A new value for option 'second' overrides a"
                         + " previous implicit setting of that option by option 'first'");
  }

  @Test
  public void warningForExplicitOverridingImplicitOptionInSameCall() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ImplicitDependencyWarningOptions.class);
    parser.parse("--first=first", "--second=second");
    assertThat(parser.getWarnings())
        .containsExactly("Option 'second' is implicitly defined by "
                         + "option 'first'; the implicitly set value overrides the previous one");
  }

  @Test
  public void warningForImplicitOverridingImplicitOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ImplicitDependencyWarningOptions.class);
    parser.parse("--first=first");
    assertThat(parser.getWarnings()).isEmpty();
    parser.parse("--third=third");
    assertThat(parser.getWarnings())
        .containsExactly("Option 'second' is implicitly defined by both "
                         + "option 'first' and option 'third'");
  }

  public static class WarningOptions extends OptionsBase {
    @Deprecated
    @Option(name = "first",
            defaultValue = "null")
    public Void first;

    @Deprecated
    @Option(name = "second",
            allowMultiple = true,
            defaultValue = "null")
    public List<String> second;

    @Deprecated
    @Option(name = "third",
            expansion = "--fourth=true",
            abbrev = 't',
            defaultValue = "null")
    public Void third;

    @Option(name = "fourth",
            defaultValue = "false")
    public boolean fourth;
  }

  @Test
  public void deprecationWarning() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(WarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first"));
    assertEquals(Arrays.asList("Option 'first' is deprecated"), parser.getWarnings());
  }

  @Test
  public void deprecationWarningForListOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(WarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--second=a"));
    assertEquals(Arrays.asList("Option 'second' is deprecated"), parser.getWarnings());
  }

  @Test
  public void deprecationWarningForExpansionOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(WarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--third"));
    assertEquals(Arrays.asList("Option 'third' is deprecated"), parser.getWarnings());
    assertTrue(parser.getOptions(WarningOptions.class).fourth);
  }

  @Test
  public void deprecationWarningForAbbreviatedExpansionOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(WarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("-t"));
    assertEquals(Arrays.asList("Option 'third' is deprecated"), parser.getWarnings());
    assertTrue(parser.getOptions(WarningOptions.class).fourth);
  }

  public static class NewWarningOptions extends OptionsBase {
    @Option(name = "first",
            defaultValue = "null",
            deprecationWarning = "it's gone")
    public Void first;

    @Option(name = "second",
            allowMultiple = true,
            defaultValue = "null",
            deprecationWarning = "sorry, no replacement")
    public List<String> second;

    @Option(name = "third",
            expansion = "--fourth=true",
            defaultValue = "null",
            deprecationWarning = "use --forth instead")
    public Void third;

    @Option(name = "fourth",
            defaultValue = "false")
    public boolean fourth;
  }

  @Test
  public void newDeprecationWarning() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NewWarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--first"));
    assertEquals(Arrays.asList("Option 'first' is deprecated: it's gone"), parser.getWarnings());
  }

  @Test
  public void newDeprecationWarningForListOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NewWarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--second=a"));
    assertEquals(Arrays.asList("Option 'second' is deprecated: sorry, no replacement"),
        parser.getWarnings());
  }

  @Test
  public void newDeprecationWarningForExpansionOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(NewWarningOptions.class);
    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList("--third"));
    assertEquals(Arrays.asList("Option 'third' is deprecated: use --forth instead"),
        parser.getWarnings());
    assertTrue(parser.getOptions(NewWarningOptions.class).fourth);
  }

  public static class ExpansionWarningOptions extends OptionsBase {
    @Option(name = "first",
            expansion = "--second=other",
            defaultValue = "null")
    public Void first;

    @Option(name = "second",
            defaultValue = "null")
    public String second;
  }

  @Test
  public void warningForExpansionOverridingExplicitOption() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ExpansionWarningOptions.class);
    parser.parse("--second=second", "--first");
    assertThat(parser.getWarnings())
        .containsExactly("The option 'first' was expanded and now overrides a "
                         + "previous explicitly specified option 'second'");
  }

  public static class InvalidOptionConverter extends OptionsBase {
    @Option(name = "foo",
            converter = StringConverter.class,
            defaultValue = "1")
    public Integer foo;
  }

  @Test
  public void errorForInvalidOptionConverter() throws Exception {
    try {
      OptionsParser.newOptionsParser(InvalidOptionConverter.class);
    } catch (AssertionError e) {
      // Expected exception
      return;
    }
    fail();
  }

  public static class InvalidListOptionConverter extends OptionsBase {
    @Option(name = "foo",
            converter = StringConverter.class,
            defaultValue = "1",
            allowMultiple = true)
    public List<Integer> foo;
  }

  @Test
  public void errorForInvalidListOptionConverter() throws Exception {
    try {
      OptionsParser.newOptionsParser(InvalidListOptionConverter.class);
    } catch (AssertionError e) {
      // Expected exception
      return;
    }
    fail();
  }

  // This test is here to make sure that nobody accidentally changes the
  // order of the enum values and breaks the implicit assumptions elsewhere
  // in the code.
  @Test
  public void optionPrioritiesAreCorrectlyOrdered() throws Exception {
    assertEquals(5, OptionPriority.values().length);
    assertEquals(-1, OptionPriority.DEFAULT.compareTo(OptionPriority.COMPUTED_DEFAULT));
    assertEquals(-1, OptionPriority.COMPUTED_DEFAULT.compareTo(OptionPriority.RC_FILE));
    assertEquals(-1, OptionPriority.RC_FILE.compareTo(OptionPriority.COMMAND_LINE));
    assertEquals(-1, OptionPriority.COMMAND_LINE.compareTo(OptionPriority.SOFTWARE_REQUIREMENT));
  }

  public static class IntrospectionExample extends OptionsBase {
    @Option(name = "alpha",
            category = "one",
            defaultValue = "alpha")
    public String alpha;

    @Option(name = "beta",
            category = "one",
            defaultValue = "beta")
    public String beta;

    @Option(name = "gamma",
        category = "undocumented",
        defaultValue = "gamma")
    public String gamma;

    @Option(name = "delta",
        category = "undocumented",
        defaultValue = "delta")
    public String delta;

    @Option(name = "echo",
        category = "hidden",
        defaultValue = "echo")
    public String echo;
  }

  @Test
  public void asListOfUnparsedOptions() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(IntrospectionExample.class);
    parser.parse(OptionPriority.COMMAND_LINE, "source",
        Arrays.asList("--alpha=one", "--gamma=two", "--echo=three"));
    List<UnparsedOptionValueDescription> result = parser.asListOfUnparsedOptions();
    assertNotNull(result);
    assertEquals(3, result.size());

    assertEquals("alpha", result.get(0).getName());
    assertEquals(true, result.get(0).isDocumented());
    assertEquals(false, result.get(0).isHidden());
    assertEquals("one", result.get(0).getUnparsedValue());
    assertEquals("source", result.get(0).getSource());
    assertEquals(OptionPriority.COMMAND_LINE, result.get(0).getPriority());

    assertEquals("gamma", result.get(1).getName());
    assertEquals(false, result.get(1).isDocumented());
    assertEquals(false, result.get(1).isHidden());
    assertEquals("two", result.get(1).getUnparsedValue());
    assertEquals("source", result.get(1).getSource());
    assertEquals(OptionPriority.COMMAND_LINE, result.get(1).getPriority());

    assertEquals("echo", result.get(2).getName());
    assertEquals(false, result.get(2).isDocumented());
    assertEquals(true, result.get(2).isHidden());
    assertEquals("three", result.get(2).getUnparsedValue());
    assertEquals("source", result.get(2).getSource());
    assertEquals(OptionPriority.COMMAND_LINE, result.get(2).getPriority());
  }

  @Test
  public void asListOfExplicitOptions() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(IntrospectionExample.class);
    parser.parse(OptionPriority.COMMAND_LINE, "source",
        Arrays.asList("--alpha=one", "--gamma=two"));
    List<UnparsedOptionValueDescription> result = parser.asListOfExplicitOptions();
    assertNotNull(result);
    assertEquals(2, result.size());

    assertEquals("alpha", result.get(0).getName());
    assertEquals(true, result.get(0).isDocumented());
    assertEquals("one", result.get(0).getUnparsedValue());
    assertEquals("source", result.get(0).getSource());
    assertEquals(OptionPriority.COMMAND_LINE, result.get(0).getPriority());

    assertEquals("gamma", result.get(1).getName());
    assertEquals(false, result.get(1).isDocumented());
    assertEquals("two", result.get(1).getUnparsedValue());
    assertEquals("source", result.get(1).getSource());
    assertEquals(OptionPriority.COMMAND_LINE, result.get(1).getPriority());
  }

  private void assertOptionValue(String expectedName, Object expectedValue,
      OptionPriority expectedPriority, String expectedSource,
      OptionValueDescription actual) {
    assertNotNull(actual);
    assertEquals(expectedName, actual.getName());
    assertEquals(expectedValue, actual.getValue());
    assertEquals(expectedPriority, actual.getPriority());
    assertEquals(expectedSource, actual.getSource());
  }

  @Test
  public void asListOfEffectiveOptions() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(IntrospectionExample.class);
    parser.parse(OptionPriority.COMMAND_LINE, "source",
        Arrays.asList("--alpha=one", "--gamma=two"));
    List<OptionValueDescription> result = parser.asListOfEffectiveOptions();
    assertNotNull(result);
    assertEquals(5, result.size());
    HashMap<String,OptionValueDescription> map = new HashMap<String,OptionValueDescription>();
    for (OptionValueDescription description : result) {
      map.put(description.getName(), description);
    }

    assertOptionValue("alpha", "one", OptionPriority.COMMAND_LINE, "source",
        map.get("alpha"));
    assertOptionValue("beta", "beta", OptionPriority.DEFAULT, null,
        map.get("beta"));
    assertOptionValue("gamma", "two", OptionPriority.COMMAND_LINE, "source",
        map.get("gamma"));
    assertOptionValue("delta", "delta", OptionPriority.DEFAULT, null,
        map.get("delta"));
    assertOptionValue("echo", "echo", OptionPriority.DEFAULT, null,
        map.get("echo"));
  }

  // Regression tests for bug:
  // "--option from blazerc unexpectedly overrides --option from command line"
  public static class ListExample extends OptionsBase {
    @Option(name = "alpha",
            converter = StringConverter.class,
            allowMultiple = true,
            defaultValue = "null")
    public List<String> alpha;
  }

  @Test
  public void overrideListOptions() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(ListExample.class);
    parser.parse(OptionPriority.COMMAND_LINE, "a", Arrays.asList("--alpha=two"));
    parser.parse(OptionPriority.RC_FILE, "b", Arrays.asList("--alpha=one"));
    assertEquals(Arrays.asList("one", "two"), parser.getOptions(ListExample.class).alpha);
  }

  public static class CommaSeparatedOptionsExample extends OptionsBase {
    @Option(name = "alpha",
            converter = CommaSeparatedOptionListConverter.class,
            allowMultiple = true,
            defaultValue = "null")
    public List<String> alpha;
  }

  @Test
  public void commaSeparatedOptionsWithAllowMultiple() throws Exception {
    OptionsParser parser = OptionsParser.newOptionsParser(CommaSeparatedOptionsExample.class);
    parser.parse(OptionPriority.COMMAND_LINE, "a", Arrays.asList("--alpha=one",
        "--alpha=two,three"));
    assertEquals(Arrays.asList("one", "two", "three"),
        parser.getOptions(CommaSeparatedOptionsExample.class).alpha);
  }

  public static class IllegalListTypeExample extends OptionsBase {
    @Option(name = "alpha",
            converter = CommaSeparatedOptionListConverter.class,
            allowMultiple = true,
            defaultValue = "null")
    public List<Integer> alpha;
  }

  @Test
  public void illegalListType() throws Exception {
    try {
      OptionsParser.newOptionsParser(IllegalListTypeExample.class);
    } catch (AssertionError e) {
      // Expected exception
      return;
    }
    fail();
  }

  public static class Yesterday extends OptionsBase {

    @Option(name = "a",
            defaultValue = "a")
    public String a;

    @Option(name = "b",
            defaultValue = "b")
    public String b;

    @Option(name = "c",
            defaultValue = "null",
            expansion = {"--a=0"})
    public Void c;

    @Option(name = "d",
            defaultValue = "null",
            allowMultiple = true)
    public List<String> d;

    @Option(name = "e",
            defaultValue = "null",
            implicitRequirements = { "--a==1" })
    public String e;

    @Option(name = "f",
            defaultValue = "null",
            implicitRequirements = { "--b==1" })
    public String f;

    @Option(name = "g",
            abbrev = 'h',
            defaultValue = "false")
    public boolean g;
  }

  public static List<String> canonicalize(Class<? extends OptionsBase> optionsClass, String... args)
      throws OptionsParsingException {
    return OptionsParser.canonicalize(ImmutableList.<Class<? extends OptionsBase>>of(optionsClass),
        Arrays.asList(args));
  }

  @Test
  public void canonicalizeEasy() throws Exception {
    assertEquals(Arrays.asList("--a=x"), canonicalize(Yesterday.class, "--a=x"));
  }

  @Test
  public void canonicalizeSkipDuplicate() throws Exception {
    assertEquals(Arrays.asList("--a=x"), canonicalize(Yesterday.class, "--a=y", "--a=x"));
  }

  @Test
  public void canonicalizeExpands() throws Exception {
    assertEquals(Arrays.asList("--a=0"), canonicalize(Yesterday.class, "--c"));
  }

  @Test
  public void canonicalizeExpansionOverridesExplicit() throws Exception {
    assertEquals(Arrays.asList("--a=0"), canonicalize(Yesterday.class, "--a=x", "--c"));
  }

  @Test
  public void canonicalizeExplicitOverridesExpansion() throws Exception {
    assertEquals(Arrays.asList("--a=x"), canonicalize(Yesterday.class, "--c", "--a=x"));
  }

  @Test
  public void canonicalizeSorts() throws Exception {
    assertEquals(Arrays.asList("--a=x", "--b=y"), canonicalize(Yesterday.class, "--b=y", "--a=x"));
  }

  @Test
  public void canonicalizeImplicitDepsAtEnd() throws Exception {
    assertEquals(Arrays.asList("--a=x", "--e=y"), canonicalize(Yesterday.class, "--e=y", "--a=x"));
  }

  @Test
  public void canonicalizeImplicitDepsSkipsDuplicate() throws Exception {
    assertEquals(Arrays.asList("--e=y"), canonicalize(Yesterday.class, "--e=x", "--e=y"));
  }

  @Test
  public void canonicalizeDoesNotSortImplicitDeps() throws Exception {
    assertEquals(Arrays.asList("--a=x", "--f=z", "--e=y"),
        canonicalize(Yesterday.class, "--f=z", "--e=y", "--a=x"));
  }

  @Test
  public void canonicalizeDoesNotSkipAllowMultiple() throws Exception {
    assertEquals(Arrays.asList("--d=a", "--d=b"),
        canonicalize(Yesterday.class, "--d=a", "--d=b"));
  }

  @Test
  public void canonicalizeReplacesAbbrevWithName() throws Exception {
    assertEquals(Arrays.asList("--g=1"),
        canonicalize(Yesterday.class, "-h"));
  }

  public static class LongValueExample extends OptionsBase {
    @Option(name = "longval",
            defaultValue = "2147483648")
    public long longval;

    @Option(name = "intval",
            defaultValue = "2147483647")
    public int intval;
  }

  @Test
  public void parseLong() throws OptionsParsingException {
    OptionsParser parser = newOptionsParser(LongValueExample.class);
    parser.parse("");
    LongValueExample result = parser.getOptions(LongValueExample.class);
    assertEquals(2147483648L, result.longval);
    assertEquals(2147483647, result.intval);

    parser.parse("--longval", Long.toString(Long.MIN_VALUE));
    result = parser.getOptions(LongValueExample.class);
    assertEquals(Long.MIN_VALUE, result.longval);

    try {
      parser.parse("--intval=2147483648");
      fail();
    } catch (OptionsParsingException e) {
    }

    parser.parse("--longval", "100");
    result = parser.getOptions(LongValueExample.class);
    assertEquals(100, result.longval);
  }
}
