// 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.cmdline.RepositoryMapping;
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 =
        StarlarkThread.createTransient(Mutability.create(), getStarlarkSemantics());
    args.addJoined(
        "--a",
        StarlarkList.of(/* mutability= */ null, "b", "c"),
        /* joinWith= */ ",",
        Starlark.NONE,
        Starlark.NONE,
        Starlark.NONE,
        false,
        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,
        false,
        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(() -> RepositoryMapping.ALWAYS_FALLBACK).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));
    }
  }
}
