// 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.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.jimfs.Jimfs;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests {@link ParamsFilePreProcessor}.
 */
@RunWith(JUnit4.class)
public class ParamsFilePreProcessorTest {
  private static final ImmutableList<String> PARAM_FILE_ARGS =
      ImmutableList.of("params", "file", "args");

  private static class MockParamsFilePreProcessor extends ParamsFilePreProcessor {

    MockParamsFilePreProcessor(FileSystem fs) {
      super(fs);
    }

    @Override
    protected List<String> parse(Path paramsFile) throws IOException, OptionsParsingException {
      return PARAM_FILE_ARGS;
    }
  }

  private FileSystem fileSystem;
  private ParamsFilePreProcessor paramsFilePreProcessor;

  @Before
  public void setup() {
    fileSystem = Jimfs.newFileSystem();
    paramsFilePreProcessor = new MockParamsFilePreProcessor(fileSystem);
  }

  @Test
  public void testNoArgs() throws OptionsParsingException {
    List<String> args = paramsFilePreProcessor.preProcess(ImmutableList.of());
    assertThat(args).isEmpty();
  }

  @Test
  public void testNoParamsFile() throws OptionsParsingException {
    List<String> rawArgs = ImmutableList.of("--foo", "foo val");
    List<String> args = paramsFilePreProcessor.preProcess(rawArgs);
    assertThat(args).containsExactlyElementsIn(rawArgs).inOrder();
  }

  @Test
  public void testParamsFileNotFirst() throws OptionsParsingException {
    List<String> rawArgs = ImmutableList.of("--foo", "foo val", "@paramsFile");
    List<String> args = paramsFilePreProcessor.preProcess(rawArgs);
    assertThat(args).containsExactlyElementsIn(rawArgs).inOrder();
  }

  @Test
  public void testTooManyArgs() throws OptionsParsingException {
    List<String> rawArgs = ImmutableList.of("@paramsFile", "--foo", "foo val");
    try {
      paramsFilePreProcessor.preProcess(rawArgs);
      fail("Expected OptionsParsingException");
    } catch (OptionsParsingException expected) {
      assertThat(expected)
          .hasMessageThat()
          .isEqualTo(
              String.format(ParamsFilePreProcessor.TOO_MANY_ARGS_ERROR_MESSAGE_FORMAT, rawArgs));
    }
  }

  @Test
  public void testExceptionDuringParsing() throws OptionsParsingException {
    ParamsFilePreProcessor exceptionParser = new ParamsFilePreProcessor(fileSystem) {
      @Override
      protected List<String> parse(Path paramsFile) throws IOException, OptionsParsingException {
        throw new IOException("Error parsing " + paramsFile);
      }
    };
    String paramsFileName = "paramsFile";
    Path paramsFile = fileSystem.getPath(paramsFileName);
    try {
      exceptionParser.preProcess(ImmutableList.of("@" + paramsFileName));
      fail("Expected OptionsParsingException");
    } catch (OptionsParsingException expected) {
      assertThat(expected)
          .hasMessageThat()
          .isEqualTo(
              String.format(
                  ParamsFilePreProcessor.ERROR_MESSAGE_FORMAT,
                  paramsFile,
                  "Error parsing " + paramsFileName));
    }
  }

  @Test
  public void testParamsFile() throws OptionsParsingException {
    List<String> args = paramsFilePreProcessor.preProcess(ImmutableList.of("@paramsFile"));
    assertThat(args).containsExactlyElementsIn(PARAM_FILE_ARGS).inOrder();
  }
}
