// Copyright 2020 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.analysis.starlark;

import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.io.CharStreams;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.util.ShellEscaper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Mutability;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Each test method checks the intermediate argument string list generated from the same {@link
 * Args} with a different param file format. The param file would be generated by writing one
 * argument per line, possibly after filtering out the positional args.
 */
@RunWith(JUnit4.class)
public class ArgsParamFileTest extends BuildViewTestCase {

  private Args args;

  /** Initializes args with a mix of "flags" and "positional arguments. */
  // TODO(bazel-team): Consider rewriting this setup as Starlark code
  @Before
  public void initArgs() throws Exception {
    args = Args.newArgs(Mutability.create(), getStarlarkSemantics());
    StarlarkThread thread = new StarlarkThread(Mutability.create(), getStarlarkSemantics());
    args.addJoined(
        "--a",
        StarlarkList.of(/* mutability= */ null, "b", "c"),
        /* joinWith= */ ",",
        Starlark.NONE,
        Starlark.NONE,
        Starlark.NONE,
        false,
        false,
        false,
        thread);
    args.addArgument("--nod", Starlark.UNBOUND, /* format= */ Starlark.NONE, thread);
    args.addArgument("pos1", Starlark.UNBOUND, /* format= */ Starlark.NONE, thread);
    args.addAll(
        "--foo",
        StarlarkList.of(/* mutability= */ null, "bar1", "bar2", "bar3"),
        Starlark.NONE,
        Starlark.NONE,
        Starlark.NONE,
        false,
        false,
        false,
        Starlark.NONE,
        thread);
    args.addArgument("--e", "'f'", /* format= */ Starlark.NONE, thread);
    args.addArgument("pos2", Starlark.UNBOUND, /* format= */ Starlark.NONE, thread);
    // Ensure a ParamFileInfo will be returned
    args.useParamsFile("%s", true);
  }

  @Test
  public void badParamFileFormat() throws Exception {
    assertThrows(EvalException.class, () -> args.setParamFileFormat("punch_cards"));
  }

  @Test
  public void setParamFileFormatTwice() throws Exception {
    args.setParamFileFormat("shell");
    assertThrows(EvalException.class, () -> args.setParamFileFormat("shell"));
  }

  @Test
  public void shell() throws Exception {
    args.setParamFileFormat("shell");
    assertThat(toParamFile(args))
        .containsExactly(
            "--a",
            "b,c",
            "--nod",
            "pos1",
            "--foo",
            "bar1",
            "bar2",
            "bar3",
            "--e",
            ShellEscaper.escapeString("'f'"),
            "pos2")
        .inOrder();
    assertThat(args.getParamFileInfo().flagsOnly()).isFalse();
  }

  @Test
  public void multiline() throws Exception {
    args.setParamFileFormat("multiline");
    assertThat(toParamFile(args))
        .containsExactly(
            "--a", "b,c", "--nod", "pos1", "--foo", "bar1", "bar2", "bar3", "--e", "'f'", "pos2")
        .inOrder();
    assertThat(args.getParamFileInfo().flagsOnly()).isFalse();
  }

  @Test
  public void flagPerLine() throws Exception {
    args.setParamFileFormat("flag_per_line");
    assertThat(toParamFile(args))
        .containsExactly("--a=b,c", "--nod", "pos1", "--foo=bar1 bar2 bar3", "--e='f'", "pos2")
        .inOrder();
    assertThat(args.getParamFileInfo().flagsOnly()).isTrue();
  }

  /**
   * Writes out the Args using ParameterFile, returns the output broken down as lines. Note, this
   * does not respect {@link ParamFileInfo#flagsOnly()}.
   */
  private static ImmutableList<String> toParamFile(Args args) throws Exception {
    byte[] bytes;
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
      ParameterFile.writeParameterFile(
          outputStream, args.build().arguments(), args.getParameterFileType(), UTF_8);
      bytes = outputStream.toByteArray();
    }
    try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        InputStreamReader reader = new InputStreamReader(inputStream, UTF_8)) {
      return ImmutableList.copyOf(CharStreams.readLines(reader));
    }
  }
}
