// 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.build.lib.runtime;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.ServerDirectories;
import com.google.devtools.build.lib.bazel.rules.BazelRulesModule;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.testutil.Scratch;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.OptionsParsingResult;
import com.google.devtools.common.options.TestOptions;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests {@link BlazeOptionHandler}.
 *
 * <p>Avoids testing anything that is controlled by the {@link BlazeCommandDispatcher}, for
 * isolation. As a part of this, this test intentionally avoids testing how errors and informational
 * messages are logged, to minimize dependence on the ui, and only checks for the existence of these
 * messages.
 */
@RunWith(JUnit4.class)
public class BlazeOptionHandlerTest {

  private final Scratch scratch = new Scratch();
  private final StoredEventHandler eventHandler = new StoredEventHandler();
  private OptionsParser parser;
  private BlazeRuntime runtime;
  private BlazeOptionHandler optionHandler;

  @Before
  public void initStuff() throws Exception {
    parser =
        OptionsParser.builder()
            .optionsClasses(TestOptions.class, CommonCommandOptions.class, ClientOptions.class)
            .allowResidue(true)
            .build();
    String productName = TestConstants.PRODUCT_NAME;
    ServerDirectories serverDirectories =
        new ServerDirectories(
            scratch.dir("install_base"), scratch.dir("output_base"), scratch.dir("user_root"));
    this.runtime =
        new BlazeRuntime.Builder()
            .setFileSystem(scratch.getFileSystem())
            .setServerDirectories(serverDirectories)
            .setProductName(productName)
            .setStartupOptionsProvider(
                OptionsParser.builder().optionsClasses(BlazeServerStartupOptions.class).build())
            .addBlazeModule(new BazelRulesModule())
            .build();
    this.runtime.overrideCommands(ImmutableList.of(new C0Command()));

    BlazeDirectories directories =
        new BlazeDirectories(
            serverDirectories,
            scratch.dir("workspace"),
            /* defaultSystemJavabase= */ null,
            productName);
    runtime.initWorkspace(directories, /*binTools=*/ null);

    optionHandler =
        new BlazeOptionHandler(
            runtime,
            runtime.getWorkspace(),
            new C0Command(),
            C0Command.class.getAnnotation(Command.class),
            parser,
            InvocationPolicy.getDefaultInstance());
  }

  @Command(
    name = "c0",
    shortDescription = "c0 desc",
    help = "c0 help",
    options = {TestOptions.class}
  )
  private static class C0Command implements BlazeCommand {
    @Override
    public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult options) {
      throw new UnsupportedOperationException();
    }

    @Override
    public void editOptions(OptionsParser optionsParser) {}
  }

  private static ListMultimap<String, RcChunkOfArgs> structuredArgsFrom2SimpleRcsWithOnlyResidue() {
    ListMultimap<String, RcChunkOfArgs> structuredArgs = ArrayListMultimap.create();
    // first add all lines of rc1, then rc2, to simulate a simple, import free, 2 rc file setup.
    structuredArgs.put("c0", new RcChunkOfArgs("rc1", ImmutableList.of("a")));
    structuredArgs.put("c0:config", new RcChunkOfArgs("rc1", ImmutableList.of("b")));

    structuredArgs.put("common", new RcChunkOfArgs("rc2", ImmutableList.of("c")));
    structuredArgs.put("c0", new RcChunkOfArgs("rc2", ImmutableList.of("d", "e")));
    structuredArgs.put("c1:other", new RcChunkOfArgs("rc2", ImmutableList.of("f", "g")));
    return structuredArgs;
  }

  private static ListMultimap<String, RcChunkOfArgs> structuredArgsFrom2SimpleRcsWithFlags() {
    ListMultimap<String, RcChunkOfArgs> structuredArgs = ArrayListMultimap.create();
    structuredArgs.put(
        "c0", new RcChunkOfArgs("rc1", ImmutableList.of("--test_multiple_string=foo")));
    structuredArgs.put(
        "c0:config", new RcChunkOfArgs("rc1", ImmutableList.of("--test_multiple_string=config")));

    structuredArgs.put(
        "common", new RcChunkOfArgs("rc2", ImmutableList.of("--test_multiple_string=common")));
    structuredArgs.put(
        "c0", new RcChunkOfArgs("rc2", ImmutableList.of("--test_multiple_string=bar")));
    structuredArgs.put(
        "c1:other", new RcChunkOfArgs("rc2", ImmutableList.of("--test_multiple_string=other")));
    return structuredArgs;
  }

  private static ListMultimap<String, RcChunkOfArgs>
      structuredArgsFromImportedRcsWithOnlyResidue() {
    ListMultimap<String, RcChunkOfArgs> structuredArgs = ArrayListMultimap.create();
    // first add all lines of rc1, then rc2, but then jump back to 1 as if rc2 was loaded in an
    // import statement halfway through rc1.
    structuredArgs.put("c0", new RcChunkOfArgs("rc1", ImmutableList.of("a")));
    structuredArgs.put("c0:config", new RcChunkOfArgs("rc1", ImmutableList.of("b")));

    structuredArgs.put("common", new RcChunkOfArgs("rc2", ImmutableList.of("c")));
    structuredArgs.put("c0", new RcChunkOfArgs("rc2", ImmutableList.of("d", "e")));
    structuredArgs.put("c1:other", new RcChunkOfArgs("rc2", ImmutableList.of("f", "g")));

    structuredArgs.put("c0", new RcChunkOfArgs("rc1", ImmutableList.of("h")));
    return structuredArgs;
  }

  private static ListMultimap<String, RcChunkOfArgs> structuredArgsForDifferentPlatforms() {
    ListMultimap<String, RcChunkOfArgs> structuredArgs = ArrayListMultimap.create();
    structuredArgs.put("c0:linux", new RcChunkOfArgs("rc1", ImmutableList.of("command_linux")));
    structuredArgs.put("c0:windows", new RcChunkOfArgs("rc1", ImmutableList.of("command_windows")));
    structuredArgs.put("c0:macos", new RcChunkOfArgs("rc1", ImmutableList.of("command_macos")));
    structuredArgs.put("c0:freebsd", new RcChunkOfArgs("rc1", ImmutableList.of("command_freebsd")));
    structuredArgs.put("c0:openbsd", new RcChunkOfArgs("rc1", ImmutableList.of("command_openbsd")));
    structuredArgs.put(
        "c0:platform_config",
        new RcChunkOfArgs("rc1", ImmutableList.of("--enable_platform_specific_config")));
    return structuredArgs;
  }

  @Test
  public void testStructureRcOptionsAndConfigs_argumentless() throws Exception {
    ListMultimap<String, RcChunkOfArgs> structuredRc =
        BlazeOptionHandler.structureRcOptionsAndConfigs(
            eventHandler,
            Arrays.asList("rc1", "rc2"),
            Arrays.asList(),
            ImmutableSet.of("c0", "c1"));
    assertThat(structuredRc).isEmpty();
    assertThat(eventHandler.isEmpty()).isTrue();
  }

  @Test
  public void testStructureRcOptionsAndConfigs_configOnly() throws Exception {
    BlazeOptionHandler.structureRcOptionsAndConfigs(
        eventHandler,
        Arrays.asList("rc1", "rc2"),
        Arrays.asList(new ClientOptions.OptionOverride(0, "c0:none", "a")),
        ImmutableSet.of("c0"));
    assertThat(eventHandler.isEmpty()).isTrue();
  }

  @Test
  public void testStructureRcOptionsAndConfigs_invalidCommand() throws Exception {
    BlazeOptionHandler.structureRcOptionsAndConfigs(
        eventHandler,
        Arrays.asList("rc1", "rc2"),
        Arrays.asList(new ClientOptions.OptionOverride(0, "c1", "a")),
        ImmutableSet.of("c0"));
    assertThat(eventHandler.getEvents())
        .contains(
            Event.warn("while reading option defaults file 'rc1':\n  invalid command name 'c1'."));
  }

  @Test
  public void testStructureRcOptionsAndConfigs_twoRcs() throws Exception {
    ListMultimap<String, RcChunkOfArgs> structuredRc =
        BlazeOptionHandler.structureRcOptionsAndConfigs(
            eventHandler,
            Arrays.asList("rc1", "rc2"),
            Arrays.asList(
                new ClientOptions.OptionOverride(0, "c0", "a"),
                new ClientOptions.OptionOverride(0, "c0:config", "b"),
                new ClientOptions.OptionOverride(1, "common", "c"),
                new ClientOptions.OptionOverride(1, "c0", "d"),
                new ClientOptions.OptionOverride(1, "c0", "e"),
                new ClientOptions.OptionOverride(1, "c1:other", "f"),
                new ClientOptions.OptionOverride(1, "c1:other", "g")),
            ImmutableSet.of("c0", "c1"));
    assertThat(structuredRc).isEqualTo(structuredArgsFrom2SimpleRcsWithOnlyResidue());
    assertThat(eventHandler.isEmpty()).isTrue();
  }

  @Test
  public void testStructureRcOptionsAndConfigs_importedRcs() throws Exception {
    ListMultimap<String, RcChunkOfArgs> structuredRc =
        BlazeOptionHandler.structureRcOptionsAndConfigs(
            eventHandler,
            Arrays.asList("rc1", "rc2"),
            Arrays.asList(
                new ClientOptions.OptionOverride(0, "c0", "a"),
                new ClientOptions.OptionOverride(0, "c0:config", "b"),
                new ClientOptions.OptionOverride(1, "common", "c"),
                new ClientOptions.OptionOverride(1, "c0", "d"),
                new ClientOptions.OptionOverride(1, "c0", "e"),
                new ClientOptions.OptionOverride(1, "c1:other", "f"),
                new ClientOptions.OptionOverride(1, "c1:other", "g"),
                new ClientOptions.OptionOverride(0, "c0", "h")),
            ImmutableSet.of("c0", "c1"));
    assertThat(structuredRc).isEqualTo(structuredArgsFromImportedRcsWithOnlyResidue());
    assertThat(eventHandler.isEmpty()).isTrue();
  }

  @Test
  public void testStructureRcOptionsAndConfigs_badOverrideIndex() throws Exception {
    ListMultimap<String, RcChunkOfArgs> structuredRc =
        BlazeOptionHandler.structureRcOptionsAndConfigs(
            eventHandler,
            Arrays.asList("rc1", "rc2"),
            Arrays.asList(
                new ClientOptions.OptionOverride(0, "c0", "a"),
                new ClientOptions.OptionOverride(0, "c0:config", "b"),
                new ClientOptions.OptionOverride(2, "c4:other", "z"),
                new ClientOptions.OptionOverride(-1, "c3:other", "q"),
                new ClientOptions.OptionOverride(1, "common", "c"),
                new ClientOptions.OptionOverride(1, "c0", "d"),
                new ClientOptions.OptionOverride(1, "c0", "e"),
                new ClientOptions.OptionOverride(1, "c1:other", "f"),
                new ClientOptions.OptionOverride(1, "c1:other", "g")),
            ImmutableSet.of("c0", "c1"));
    assertThat(structuredRc).isEqualTo(structuredArgsFrom2SimpleRcsWithOnlyResidue());
    assertThat(eventHandler.getEvents())
        .containsAtLeast(
            Event.warn("inconsistency in generated command line args. Ignoring bogus argument\n"),
            Event.warn("inconsistency in generated command line args. Ignoring bogus argument\n"));
  }

  @Test
  public void testParseRcOptions_empty() throws Exception {
    optionHandler.parseRcOptions(eventHandler, ArrayListMultimap.create());
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
  }

  @Test
  public void testParseRcOptions_flatRcs_residue() throws Exception {
    optionHandler.parseRcOptions(eventHandler, structuredArgsFrom2SimpleRcsWithOnlyResidue());
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).containsExactly("c", "a", "d", "e").inOrder();
  }

  @Test
  public void testParseRcOptions_flatRcs_flags() throws Exception {
    optionHandler.parseRcOptions(eventHandler, structuredArgsFrom2SimpleRcsWithFlags());
    assertThat(eventHandler.getEvents()).isEmpty();
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("common", "foo", "bar").inOrder();
  }

  @Test
  public void testParseRcOptions_importedRcs_residue() throws Exception {
    optionHandler.parseRcOptions(eventHandler, structuredArgsFromImportedRcsWithOnlyResidue());
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).containsExactly("c", "a", "d", "e", "h").inOrder();
  }

  @Test
  public void testExpandConfigOptions_configless() throws Exception {
    optionHandler.expandConfigOptions(eventHandler, structuredArgsFrom2SimpleRcsWithOnlyResidue());
    assertThat(parser.getResidue()).isEmpty();
  }

  @Test
  public void testExpandConfigOptions_withConfig() throws Exception {
    parser.parse("--config=config");
    optionHandler.expandConfigOptions(eventHandler, structuredArgsFrom2SimpleRcsWithOnlyResidue());
    assertThat(parser.getResidue()).containsExactly("b");
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly("Found applicable config definition c0:config in file rc1: b");
  }

  @Test
  public void testExpandConfigOptions_withPlatformSpecificConfigEnabled() throws Exception {
    parser.parse("--enable_platform_specific_config");
    optionHandler.expandConfigOptions(eventHandler, structuredArgsForDifferentPlatforms());
    switch (OS.getCurrent()) {
      case LINUX:
        assertThat(parser.getResidue()).containsExactly("command_linux");
        break;
      case DARWIN:
        assertThat(parser.getResidue()).containsExactly("command_macos");
        break;
      case WINDOWS:
        assertThat(parser.getResidue()).containsExactly("command_windows");
        break;
      case FREEBSD:
        assertThat(parser.getResidue()).containsExactly("command_freebsd");
        break;
      case OPENBSD:
        assertThat(parser.getResidue()).containsExactly("command_openbsd");
        break;
      default:
        assertThat(parser.getResidue()).isEmpty();
    }
  }

  @Test
  public void testExpandConfigOptions_withPlatformSpecificConfigEnabledInConfig() throws Exception {
    // --enable_platform_specific_config itself will affect the selecting of config sections.
    // Because Bazel expands config sections recursively, we want to make sure it's fine to enable
    // --enable_platform_specific_config via another config section.
    parser.parse("--config=platform_config");
    optionHandler.expandConfigOptions(eventHandler, structuredArgsForDifferentPlatforms());
    switch (OS.getCurrent()) {
      case LINUX:
        assertThat(parser.getResidue()).containsExactly("command_linux");
        break;
      case DARWIN:
        assertThat(parser.getResidue()).containsExactly("command_macos");
        break;
      case WINDOWS:
        assertThat(parser.getResidue()).containsExactly("command_windows");
        break;
      case FREEBSD:
        assertThat(parser.getResidue()).containsExactly("command_freebsd");
        break;
      case OPENBSD:
        assertThat(parser.getResidue()).containsExactly("command_openbsd");
        break;
      default:
        assertThat(parser.getResidue()).isEmpty();
    }
  }

  @Test
  public void testExpandConfigOptions_withPlatformSpecificConfigEnabledWhenNothingSpecified()
      throws Exception {
    parser.parse("--enable_platform_specific_config");
    optionHandler.parseRcOptions(eventHandler, ArrayListMultimap.create());
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
  }

  @Test
  public void testExpandConfigOptions_withConfigForUnapplicableCommand() throws Exception {
    parser.parse("--config=other");
    OptionsParsingException e =
        assertThrows(
            OptionsParsingException.class,
            () ->
                optionHandler.expandConfigOptions(
                    eventHandler, structuredArgsFrom2SimpleRcsWithOnlyResidue()));
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
    assertThat(e).hasMessageThat().contains("Config value other is not defined in any .rc file");
  }

  @Test
  public void testUndefinedConfig() throws Exception {
    parser.parse("--config=invalid");
    OptionsParsingException e =
        assertThrows(
            OptionsParsingException.class,
            () -> optionHandler.expandConfigOptions(eventHandler, ArrayListMultimap.create()));
    assertThat(e).hasMessageThat().contains("Config value invalid is not defined in any .rc file");
  }

  @Test
  public void testParseOptions_argless() {
    optionHandler.parseOptions(ImmutableList.of("c0"), eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
  }

  @Test
  public void testParseOptions_residue() {
    optionHandler.parseOptions(ImmutableList.of("c0", "res"), eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).contains("res");
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
  }

  @Test
  public void testParseOptions_explicitOption() {
    optionHandler.parseOptions(
        ImmutableList.of("c0", "--test_multiple_string=explicit"), eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("explicit");
  }

  @Test
  public void testParseOptions_rcOption() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc_a",
            "--default_override=0:c0=--test_multiple_string=rc_b",
            "--rc_source=/somewhere/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    // Check that multiple options in the same rc chunk are collapsed into 1 announce_rc entry.
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc_a --test_multiple_string=rc_b");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("rc_a", "rc_b");
  }

  @Test
  public void testParseOptions_multipleRcs() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc1_a",
            "--default_override=1:c0=--test_multiple_string=rc2",
            "--default_override=0:c0=--test_multiple_string=rc1_b",
            "--rc_source=/somewhere/.blazerc",
            "--rc_source=/some/other/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_a",
            "Reading rc options for 'c0' from /some/other/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc2",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_b");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("rc1_a", "rc2", "rc1_b").inOrder();
  }

  @Test
  public void testParseOptions_multipleRcsWithMultipleCommands() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc1_a",
            "--default_override=1:c0=--test_multiple_string=rc2",
            "--default_override=1:common=--test_multiple_string=rc2_common",
            "--default_override=0:c0=--test_multiple_string=rc1_b",
            "--default_override=0:common=--test_multiple_string=rc1_common",
            "--rc_source=/somewhere/.blazerc",
            "--rc_source=/some/other/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /some/other/.blazerc:\n"
                + "  Inherited 'common' options: --test_multiple_string=rc2_common",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  Inherited 'common' options: --test_multiple_string=rc1_common",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_a",
            "Reading rc options for 'c0' from /some/other/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc2",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_b");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly("rc2_common", "rc1_common", "rc1_a", "rc2", "rc1_b")
        .inOrder();
  }

  @Test
  public void testParseOptions_rcOptionAndExplicit() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("rc", "explicit").inOrder();
  }

  @Test
  public void testParseOptions_multiCommandRcOptionAndExplicit() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc_c0_1",
            "--default_override=0:common=--test_multiple_string=rc_common",
            "--default_override=0:c0=--test_multiple_string=rc_c0_2",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  Inherited 'common' options: --test_multiple_string=rc_common",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc_c0_1 --test_multiple_string=rc_c0_2");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly("rc_common", "rc_c0_1", "rc_c0_2", "explicit")
        .inOrder();
  }

  @Test
  public void testParseOptions_multipleRcsWithMultipleCommandsPlusExplicitOption() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc1_a",
            "--default_override=1:c0=--test_multiple_string=rc2",
            "--test_multiple_string=explicit",
            "--default_override=1:common=--test_multiple_string=rc2_common",
            "--default_override=0:c0=--test_multiple_string=rc1_b",
            "--default_override=0:common=--test_multiple_string=rc1_common",
            "--rc_source=/somewhere/.blazerc",
            "--rc_source=/some/other/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /some/other/.blazerc:\n"
                + "  Inherited 'common' options: --test_multiple_string=rc2_common",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  Inherited 'common' options: --test_multiple_string=rc1_common",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_a",
            "Reading rc options for 'c0' from /some/other/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc2",
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc1_b");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly("rc2_common", "rc1_common", "rc1_a", "rc2", "rc1_b", "explicit")
        .inOrder();
  }

  @Test
  public void testParseOptions_explicitConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:conf=--test_multiple_string=config",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit",
            "--config=conf"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --test_multiple_string=rc",
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_multiple_string=config");

    // "config" is expanded from --config=conf, which occurs last.
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("rc", "explicit", "config").inOrder();
  }

  @Test
  public void testParseOptions_rcSpecifiedConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=conf",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:conf=--test_multiple_string=config",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --config=conf --test_multiple_string=rc",
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_multiple_string=config");

    // "config" is expanded from --config=conf, which occurs before the explicit mention of "rc".
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString).containsExactly("config", "rc", "explicit").inOrder();
  }

  @Test
  public void testParseOptions_recursiveConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=conf",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:other=--test_multiple_string=other",
            "--default_override=0:c0:conf=--test_multiple_string=config1",
            "--default_override=0:c0:conf=--config=other",
            "--default_override=0:common:other=--test_multiple_string=othercommon",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --config=conf --test_multiple_string=rc",
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_multiple_string=config1 --config=other",
            "Found applicable config definition common:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=othercommon",
            "Found applicable config definition c0:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=other");

    // The 2nd config, --config=other, is added by --config=conf after conf adds its own value.
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly("config1", "othercommon", "other", "rc", "explicit")
        .inOrder();
  }

  @Test
  public void testParseOptions_recursiveConfigWithDifferentTokens() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:other=--test_multiple_string=other",
            "--default_override=0:c0:conf=--test_multiple_string=config1",
            "--default_override=0:c0:conf=--config",
            "--default_override=0:c0:conf=other",
            "--rc_source=/somewhere/.blazerc",
            "--config=conf"),
        eventHandler);

    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.error(
                "In file /somewhere/.blazerc, the definition of config conf expands to another "
                    + "config that either has no value or is not in the form --config=value. For "
                    + "recursive config definitions, please do not provide the value in a "
                    + "separate token, such as in the form '--config value'."));
  }

  @Test
  public void testParseOptions_complexConfigOrder() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--test_multiple_string=rc1",
            "--default_override=0:c0=--config=foo",
            "--default_override=0:c0=--test_multiple_string=rc2",
            "--default_override=0:common:baz=--test_multiple_string=baz1",
            "--default_override=0:c0:baz=--test_multiple_string=baz2",
            "--default_override=0:common:foo=--test_multiple_string=foo1",
            "--default_override=0:common:foo=--config=bar",
            "--default_override=0:c0:foo=--test_multiple_string=foo3",
            "--default_override=0:common:foo=--test_multiple_string=foo2",
            "--default_override=0:c0:foo=--test_multiple_string=foo4",
            "--default_override=0:common:bar=--test_multiple_string=bar1",
            "--default_override=0:c0:bar=--test_multiple_string=bar2",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit1",
            "--config=baz",
            "--test_multiple_string=explicit2"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n  'c0' options: "
                + "--test_multiple_string=rc1 --config=foo --test_multiple_string=rc2",
            "Found applicable config definition common:foo in file /somewhere/.blazerc: "
                + "--test_multiple_string=foo1 --config=bar --test_multiple_string=foo2",
            "Found applicable config definition common:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar1",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar2",
            "Found applicable config definition c0:foo in file /somewhere/.blazerc: "
                + "--test_multiple_string=foo3 --test_multiple_string=foo4",
            "Found applicable config definition common:baz in file /somewhere/.blazerc: "
                + "--test_multiple_string=baz1",
            "Found applicable config definition c0:baz in file /somewhere/.blazerc: "
                + "--test_multiple_string=baz2");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly(
            "rc1",
            "foo1",
            "bar1",
            "bar2",
            "foo2",
            "foo3",
            "foo4",
            "rc2",
            "explicit1",
            "baz1",
            "baz2",
            "explicit2")
        .inOrder();
  }

  @Test
  public void testParseOptions_repeatSubConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=foo",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:foo=--test_multiple_string=foo",
            "--default_override=0:c0:foo=--config=bar",
            "--default_override=0:c0:foo=--config=bar",
            "--default_override=0:c0:bar=--test_multiple_string=bar",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(parser.getResidue()).isEmpty();
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "The following configs were expanded more than once: [bar]. For repeatable flags, "
                    + "repeats are counted twice and may lead to unexpected behavior."));
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --config=foo --test_multiple_string=rc",
            "Found applicable config definition c0:foo in file /somewhere/.blazerc: "
                + "--test_multiple_string=foo --config=bar --config=bar",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    // Bar is repeated, since it was included twice.
    assertThat(options.testMultipleString)
        .containsExactly("foo", "bar", "bar", "rc", "explicit")
        .inOrder();
  }

  @Test
  public void testParseOptions_repeatConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0:foo=--test_multiple_string=foo",
            "--default_override=0:c0:foo=--config=bar",
            "--default_override=0:c0:bar=--test_multiple_string=bar",
            "--default_override=0:c0:baz=--test_multiple_string=baz",
            "--rc_source=/somewhere/.blazerc",
            "--config=foo",
            "--config=baz",
            "--config=foo",
            "--config=bar"),
        eventHandler);
    assertThat(parser.getResidue()).isEmpty();
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "The following configs were expanded more than once: [foo, bar]. For repeatable "
                    + "flags, repeats are counted twice and may lead to unexpected behavior."));
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Found applicable config definition c0:foo in file /somewhere/.blazerc: "
                + "--test_multiple_string=foo --config=bar",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar",
            "Found applicable config definition c0:baz in file /somewhere/.blazerc: "
                + "--test_multiple_string=baz",
            "Found applicable config definition c0:foo in file /somewhere/.blazerc: "
                + "--test_multiple_string=foo --config=bar",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar",
            "Found applicable config definition c0:bar in file /somewhere/.blazerc: "
                + "--test_multiple_string=bar");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    // Bar is repeated, since it was included twice.
    assertThat(options.testMultipleString)
        .containsExactly("foo", "bar", "baz", "foo", "bar", "bar")
        .inOrder();
  }

  @Test
  public void testParseOptions_configCycleLength1() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=foo",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:foo=--test_multiple_string=foo",
            "--default_override=0:c0:foo=--config=foo",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents())
        .contains(
            Event.error(
                "Config expansion has a cycle: config value foo expands to itself, see "
                    + "inheritance chain [foo]"));
  }

  @Test
  public void testParseOptions_configCycleLength2() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=foo",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:foo=--test_multiple_string=foo",
            "--default_override=0:c0:foo=--config=bar",
            "--default_override=0:c0:bar=--test_multiple_string=bar",
            "--default_override=0:c0:bar=--config=foo",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(eventHandler.getEvents())
        .contains(
            Event.error(
                "Config expansion has a cycle: config value foo expands to itself, see "
                    + "inheritance chain [foo, bar]"));
  }

  @Test
  public void testParseOptions_recursiveConfigWasAlreadyPresent() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0=--config=other",
            "--default_override=0:c0=--config=conf",
            "--default_override=0:c0=--test_multiple_string=rc",
            "--default_override=0:c0:other=--test_multiple_string=other",
            "--default_override=0:c0:conf=--test_multiple_string=config1",
            "--default_override=0:c0:conf=--config=other",
            "--default_override=0:common:other=--test_multiple_string=othercommon",
            "--rc_source=/somewhere/.blazerc",
            "--test_multiple_string=explicit"),
        eventHandler);
    assertThat(parser.getResidue()).isEmpty();
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "The following configs were expanded more than once: [other]. For repeatable "
                    + "flags, repeats are counted twice and may lead to unexpected behavior."));

    // The 2nd config, --config=other, is expanded twice at the same time as --config=conf,
    // both initially present. The "common" definition is therefore first. other is expanded twice.
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Reading rc options for 'c0' from /somewhere/.blazerc:\n"
                + "  'c0' options: --config=other --config=conf --test_multiple_string=rc",
            "Found applicable config definition common:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=othercommon",
            "Found applicable config definition c0:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=other",
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_multiple_string=config1 --config=other",
            "Found applicable config definition common:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=othercommon",
            "Found applicable config definition c0:other in file /somewhere/.blazerc: "
                + "--test_multiple_string=other");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly(
            "othercommon", "other", "config1", "othercommon", "other", "rc", "explicit")
        .inOrder();
  }

  private static final ImmutableList<String> GREEK_ALPHABET_CHAIN =
      ImmutableList.of(
          "--default_override=0:c0:alpha=--test_multiple_string=alpha",
          "--default_override=0:c0:alpha=--config=beta",
          "--default_override=0:c0:beta=--test_multiple_string=beta",
          "--default_override=0:c0:beta=--config=gamma",
          "--default_override=0:c0:gamma=--test_multiple_string=gamma",
          "--default_override=0:c0:gamma=--config=delta",
          "--default_override=0:c0:delta=--test_multiple_string=delta",
          "--default_override=0:c0:delta=--config=epsilon",
          "--default_override=0:c0:epsilon=--test_multiple_string=epsilon",
          "--default_override=0:c0:epsilon=--config=zeta",
          "--default_override=0:c0:zeta=--test_multiple_string=zeta",
          "--default_override=0:c0:zeta=--config=eta",
          "--default_override=0:c0:eta=--test_multiple_string=eta",
          "--default_override=0:c0:eta=--config=theta",
          "--default_override=0:c0:theta=--test_multiple_string=theta",
          "--default_override=0:c0:theta=--config=iota",
          "--default_override=0:c0:iota=--test_multiple_string=iota",
          "--default_override=0:c0:iota=--config=kappa",
          "--default_override=0:c0:kappa=--test_multiple_string=kappa",
          "--default_override=0:c0:kappa=--config=lambda",
          "--default_override=0:c0:lambda=--test_multiple_string=lambda",
          "--default_override=0:c0:lambda=--config=mu",
          "--default_override=0:c0:mu=--test_multiple_string=mu");

  @Test
  public void testParseOptions_longChain() {
    ImmutableList<String> args =
        ImmutableList.<String>builder()
            .add("c0")
            .addAll(GREEK_ALPHABET_CHAIN)
            .add("--rc_source=/somewhere/.blazerc")
            .add("--config=alpha")
            .build();

    optionHandler.parseOptions(args, eventHandler);
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Found applicable config definition c0:alpha in file /somewhere/.blazerc: "
                + "--test_multiple_string=alpha --config=beta",
            "Found applicable config definition c0:beta in file /somewhere/.blazerc: "
                + "--test_multiple_string=beta --config=gamma",
            "Found applicable config definition c0:gamma in file /somewhere/.blazerc: "
                + "--test_multiple_string=gamma --config=delta",
            "Found applicable config definition c0:delta in file /somewhere/.blazerc: "
                + "--test_multiple_string=delta --config=epsilon",
            "Found applicable config definition c0:epsilon in file /somewhere/.blazerc: "
                + "--test_multiple_string=epsilon --config=zeta",
            "Found applicable config definition c0:zeta in file /somewhere/.blazerc: "
                + "--test_multiple_string=zeta --config=eta",
            "Found applicable config definition c0:eta in file /somewhere/.blazerc: "
                + "--test_multiple_string=eta --config=theta",
            "Found applicable config definition c0:theta in file /somewhere/.blazerc: "
                + "--test_multiple_string=theta --config=iota",
            "Found applicable config definition c0:iota in file /somewhere/.blazerc: "
                + "--test_multiple_string=iota --config=kappa",
            "Found applicable config definition c0:kappa in file /somewhere/.blazerc: "
                + "--test_multiple_string=kappa --config=lambda",
            "Found applicable config definition c0:lambda in file /somewhere/.blazerc: "
                + "--test_multiple_string=lambda --config=mu",
            "Found applicable config definition c0:mu in file /somewhere/.blazerc: "
                + "--test_multiple_string=mu");
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly(
            "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa",
            "lambda", "mu")
        .inOrder();
    // Expect only one warning, we don't want multiple warnings for the same chain.
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "There is a recursive chain of configs 12 configs long: [alpha, beta, gamma, "
                    + "delta, epsilon, zeta, eta, theta, iota, kappa, lambda, mu]. This seems "
                    + "excessive, and might be hiding errors."));
  }

  @Test
  public void testParseOptions_2LongChains() {
    ImmutableList<String> args =
        ImmutableList.<String>builder()
            .add("c0")
            .addAll(GREEK_ALPHABET_CHAIN)
            .add("--rc_source=/somewhere/.blazerc")
            .add("--config=alpha")
            .add("--config=gamma")
            .build();

    optionHandler.parseOptions(args, eventHandler);
    assertThat(parser.getResidue()).isEmpty();

    // Expect the second --config=gamma to have started a second chain, and get warnings about both.
    TestOptions options = parser.getOptions(TestOptions.class);
    assertThat(options).isNotNull();
    assertThat(options.testMultipleString)
        .containsExactly(
            "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa",
            "lambda", "mu", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa",
            "lambda", "mu")
        .inOrder();
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "There is a recursive chain of configs 12 configs long: [alpha, beta, gamma, "
                    + "delta, epsilon, zeta, eta, theta, iota, kappa, lambda, mu]. This seems "
                    + "excessive, and might be hiding errors."),
            Event.warn(
                "There is a recursive chain of configs 10 configs long: [gamma, delta, epsilon, "
                    + "zeta, eta, theta, iota, kappa, lambda, mu]. This seems excessive, "
                    + "and might be hiding errors."),
            Event.warn(
                "The following configs were expanded more than once: [gamma, delta, epsilon, zeta, "
                    + "eta, theta, iota, kappa, lambda, mu]. For repeatable flags, repeats are "
                    + "counted twice and may lead to unexpected behavior."));
  }

  @Test
  public void testWarningFlag() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--unconditional_warning",
            "You are forcing this warning to print for no apparent reason"),
        eventHandler);
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn("You are forcing this warning to print for no apparent reason"));
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
  }

  @Test
  public void testWarningFlag_byConfig_notTriggered() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--default_override=0:c0:conf=--unconditional_warning="
                + "config \"conf\" is deprecated, please stop using!",
            "--rc_source=/somewhere/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes()).isEmpty();
  }

  @Test
  public void testWarningFlag_byConfig_triggered() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--config=conf",
            "--default_override=0:c0:conf=--unconditional_warning="
                + "config \"conf\" is deprecated, please stop using!",
            "--rc_source=/somewhere/.blazerc"),
        eventHandler);
    assertThat(eventHandler.getEvents())
        .containsExactly(Event.warn("config \"conf\" is deprecated, please stop using!"));
    assertThat(parser.getResidue()).isEmpty();
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--unconditional_warning=config \"conf\" is deprecated, please stop using!");
  }

  @Test
  public void testConfigAfterExplicit() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--test_string=explicitValue",
            "--config=conf",
            "--default_override=0:c0:conf=--test_string=fromConf",
            "--rc_source=/somewhere/.blazerc"),
        eventHandler);
    TestOptions parseResult = parser.getOptions(TestOptions.class);
    // In the in-place expansion, the config's expansion has precedence, but issues a warning since
    // users might not know that their explicit value was overridden.
    assertThat(eventHandler.getEvents())
        .containsExactly(
            Event.warn(
                "option '--config=conf' (source command line options) was expanded and now "
                    + "overrides the explicit option --test_string=explicitValue with "
                    + "--test_string=fromConf"));
    assertThat(parseResult.testString).isEqualTo("fromConf");
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_string=fromConf");
  }

  @Test
  public void testExplicitOverridesConfig() {
    optionHandler.parseOptions(
        ImmutableList.of(
            "c0",
            "--config=conf",
            "--test_string=explicitValue",
            "--default_override=0:c0:conf=--test_string=fromConf",
            "--rc_source=/somewhere/.blazerc"),
        eventHandler);
    TestOptions parseResult = parser.getOptions(TestOptions.class);
    assertThat(eventHandler.getEvents()).isEmpty();
    assertThat(parseResult.testString).isEqualTo("explicitValue");
    assertThat(optionHandler.getRcfileNotes())
        .containsExactly(
            "Found applicable config definition c0:conf in file /somewhere/.blazerc: "
                + "--test_string=fromConf");
  }
}
