// Copyright 2016 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.windows;

import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_16LE;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Joiner;
import com.google.devtools.build.lib.shell.ShellUtils;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.windows.jni.WindowsProcesses;
import com.google.devtools.build.runfiles.Runfiles;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Unit tests for {@link WindowsProcesses}.
 */
@RunWith(JUnit4.class)
@TestSpec(localOnly = true, supportedOs = OS.WINDOWS)
public class WindowsProcessesTest {
  private String mockSubprocess;
  private String mockBinary;
  private long process;

  @Before
  public void loadJni() throws Exception {
    Runfiles runfiles = Runfiles.create();
    mockSubprocess =
        runfiles.rlocation(
            "io_bazel/src/test/java/com/google/devtools/build/lib/MockSubprocess_deploy.jar");
    mockBinary = System.getProperty("java.home") + "\\bin\\java.exe";

    process = -1;
  }

  @After
  public void terminateProcess() throws Exception {
    if (process != -1) {
      WindowsProcesses.terminate(process);
      WindowsProcesses.deleteProcess(process);
      process = -1;
    }
  }

  private static List<String> quoteArgs(List<String> argv, String... args) {
    for (String arg : args) {
      argv.add(ShellUtils.windowsEscapeArg(arg));
    }
    return argv;
  }

  private static List<String> quoteArgs(String... args) {
    List<String> argv = new ArrayList<>();
    return quoteArgs(argv, args);
  }

  private String mockArgs(String... args) {
    List<String> argv = new ArrayList<>();

    argv.add("-jar");
    argv.add(mockSubprocess);
    quoteArgs(argv, args);

    return Joiner.on(" ").join(argv);
  }

  private void assertNoProcessError() throws Exception {
    assertThat(WindowsProcesses.processGetLastError(process)).isEmpty();
  }

  private void assertNoStreamError(long stream) throws Exception {
    assertThat(WindowsProcesses.streamGetLastError(stream)).isEmpty();
  }

  @Test
  public void testDoesNotQuoteSimpleArg() throws Exception {
    assertThat(quoteArgs("x", "a")).containsExactly("x", "a").inOrder();
  }

  @Test
  public void testQuotesEmptyArg() throws Exception {
    assertThat(quoteArgs("x", "")).containsExactly("x", "\"\"").inOrder();
  }

  @Test
  public void testQuotesArgWithSpace() throws Exception {
    assertThat(quoteArgs("x", "a b")).containsExactly("x", "\"a b\"").inOrder();
  }

  @Test
  public void testDoesNotQuoteArgWithBackslash() throws Exception {
    assertThat(quoteArgs("x", "a\\b")).containsExactly("x", "a\\b").inOrder();
  }

  @Test
  public void testDoesNotQuoteArgWithSingleQuote() throws Exception {
    assertThat(quoteArgs("x", "a'b")).containsExactly("x", "a'b").inOrder();
  }

  @Test
  public void testQuotesArgWithDoubleQuote() throws Exception {
    assertThat(quoteArgs("x", "a\"b", "y")).containsExactly("x", "\"a\\\"b\"", "y").inOrder();
  }

  @Test
  public void testSmoke() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("Ia5", "Oa"), null, null, null, null);
    assertNoProcessError();

    byte[] input = "HELLO".getBytes(UTF_8);
    byte[] output = new byte[5];
    WindowsProcesses.writeStdin(process, input, 0, 5);
    assertNoProcessError();
    readStdout(output, 0, 5);
    assertNoStreamError(WindowsProcesses.getStdout(process));
    assertThat(new String(output, UTF_8)).isEqualTo("HELLO");
  }

  @Test
  public void testPingpong() throws Exception {
    List<String> args = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
      args.add("Ia3");
      args.add("Oa");
    }

    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs(args.toArray(new String[] {})), null, null, null, null);
    for (int i = 0; i < 100; i++) {
      byte[] input = String.format("%03d", i).getBytes(UTF_8);
      assertThat(input.length).isEqualTo(3);
      assertThat(WindowsProcesses.writeStdin(process, input, 0, 3)).isEqualTo(3);
      byte[] output = new byte[3];
      assertThat(readStdout(output, 0, 3)).isEqualTo(3);
      assertThat(Integer.parseInt(new String(output, UTF_8))).isEqualTo(i);
    }
  }

  private int readStdout(byte[] output, int offset, int length) {
    return WindowsProcesses.readStream(
        WindowsProcesses.getStdout(process), output, offset, length);
  }

  private int readStderr(byte[] output, int offset, int length) {
    return WindowsProcesses.readStream(
        WindowsProcesses.getStderr(process), output, offset, length);
  }

  @Test
  public void testExitCode() throws Exception {
    process =
        WindowsProcesses.createProcess(mockBinary, mockArgs("X42"), null, null, null, null);
    assertThat(WindowsProcesses.waitFor(process, -1)).isEqualTo(0);
    assertThat(WindowsProcesses.getExitCode(process)).isEqualTo(42);
    assertNoProcessError();
  }

  @Test
  public void testPartialRead() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-HELLO"), null, null, null, null);
    byte[] one = new byte[2];
    byte[] two = new byte[3];

    assertThat(readStdout(one, 0, 2)).isEqualTo(2);
    assertNoStreamError(WindowsProcesses.getStdout(process));
    assertThat(readStdout(two, 0, 3)).isEqualTo(3);
    assertNoStreamError(WindowsProcesses.getStdout(process));

    assertThat(new String(one, UTF_8)).isEqualTo("HE");
    assertThat(new String(two, UTF_8)).isEqualTo("LLO");
  }

  @Test
  public void testArrayOutOfBounds() throws Exception {
    process =
        WindowsProcesses.createProcess(mockBinary, mockArgs("O-oob"), null, null, null, null);
    byte[] buf = new byte[3];
    assertThat(readStdout(buf, -1, 3)).isEqualTo(-1);
    assertThat(readStdout(buf, 0, 5)).isEqualTo(-1);
    assertThat(readStdout(buf, 4, 1)).isEqualTo(-1);
    assertThat(readStdout(buf, 2, -1)).isEqualTo(-1);
    assertThat(readStdout(buf, Integer.MAX_VALUE, 2)).isEqualTo(-1);
    assertThat(readStdout(buf, 2, Integer.MAX_VALUE)).isEqualTo(-1);
    assertThat(readStderr(buf, -1, 3)).isEqualTo(-1);
    assertThat(readStderr(buf, 0, 5)).isEqualTo(-1);
    assertThat(readStderr(buf, 4, 1)).isEqualTo(-1);
    assertThat(readStderr(buf, 2, -1)).isEqualTo(-1);
    assertThat(readStderr(buf, Integer.MAX_VALUE, 2)).isEqualTo(-1);
    assertThat(readStderr(buf, 2, Integer.MAX_VALUE)).isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, -1, 3)).isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, 0, 5)).isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, 4, 1)).isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, 2, -1)).isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, Integer.MAX_VALUE, 2))
        .isEqualTo(-1);
    assertThat(WindowsProcesses.writeStdin(process, buf, 2, Integer.MAX_VALUE))
        .isEqualTo(-1);

    assertThat(readStdout(buf, 0, 3)).isEqualTo(3);
    assertThat(new String(buf, UTF_8)).isEqualTo("oob");
  }

  @Test
  public void testOffsetedOps() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("Ia3", "Oa"), null, null, null, null);
    byte[] input = "01234".getBytes(UTF_8);
    byte[] output = "abcde".getBytes(UTF_8);

    assertThat(WindowsProcesses.writeStdin(process, input, 1, 3)).isEqualTo(3);
    assertNoProcessError();
    int rv = readStdout(output, 1, 3);
    assertNoProcessError();
    assertThat(rv).isEqualTo(3);

    assertThat(new String(output, UTF_8)).isEqualTo("a123e");
  }

  @Test
  public void testParallelStdoutAndStderr() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary,
            mockArgs(
                "O-out1", "E-err1", "O-out2", "E-err2", "E-err3", "O-out3", "E-err4", "O-out4"),
            null,
            null,
            null,
            null);
    assertNoProcessError();

    byte[] buf = new byte[4];
    assertThat(readStdout(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("out1");
    assertThat(readStderr(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("err1");

    assertThat(readStderr(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("err2");
    assertThat(readStdout(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("out2");

    assertThat(readStdout(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("out3");
    assertThat(readStderr(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("err3");

    assertThat(readStderr(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("err4");
    assertThat(readStdout(buf, 0, 4)).isEqualTo(4);
    assertThat(new String(buf, UTF_8)).isEqualTo("out4");
  }

  @Test
  public void testExecutableNotFound() throws Exception {
    process =
        WindowsProcesses.createProcess(
            "ThisExecutableDoesNotExist", "TheseArgsDontMatter", null, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process))
        .contains("The system cannot find the file specified.");
    byte[] buf = new byte[1];
    assertThat(readStdout(buf, 0, 1)).isEqualTo(0);
  }

  @Test
  public void testReadingAndWritingAfterTermination() throws Exception {
    process =
        WindowsProcesses.createProcess(mockBinary, mockArgs("X42"), null, null, null, null);
    byte[] buf = new byte[1];
    assertThat(readStdout(buf, 0, 1)).isEqualTo(0);
    assertThat(readStderr(buf, 0, 1)).isEqualTo(0);
    assertThat(WindowsProcesses.writeStdin(process, buf, 0, 1)).isEqualTo(-1);
  }

  @Test
  public void testNewEnvironmentVariables() throws Exception {
    byte[] data = "ONE=one\0TWO=twotwo\0\0".getBytes(UTF_16LE);
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O$ONE", "O$TWO"), data, null, null, null);
    assertNoProcessError();
    byte[] buf = new byte[3];
    assertThat(readStdout(buf, 0, 3)).isEqualTo(3);
    assertThat(new String(buf, UTF_8)).isEqualTo("one");
    buf = new byte[6];
    assertThat(readStdout(buf, 0, 6)).isEqualTo(6);
    assertThat(new String(buf, UTF_8)).isEqualTo("twotwo");
  }

  @Test
  public void testNoZeroInEnvBuffer() throws Exception {
    byte[] data = "clown".getBytes(UTF_16LE);
    process = WindowsProcesses.createProcess(mockBinary, mockArgs(), data, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process)).isNotEmpty();
  }

  @Test
  public void testMissingFinalDoubleZeroInEnvBuffer() throws Exception {
    byte[] data = "FOO=bar\0".getBytes(UTF_16LE);
    process = WindowsProcesses.createProcess(mockBinary, mockArgs(), data, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process)).isNotEmpty();
  }

  @Test
  public void testOneByteEnvBuffer() throws Exception {
    byte[] data = "a".getBytes(UTF_16LE);
    process = WindowsProcesses.createProcess(mockBinary, mockArgs(), data, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process)).isNotEmpty();
  }

  @Test
  public void testOneZeroEnvBuffer() throws Exception {
    byte[] data = "\0".getBytes(UTF_16LE);
    process = WindowsProcesses.createProcess(mockBinary, mockArgs(), data, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process)).isNotEmpty();
  }

  @Test
  public void testTwoZerosInEnvBuffer() throws Exception {
    byte[] data = "\0\0".getBytes(UTF_16LE);
    process = WindowsProcesses.createProcess(mockBinary, mockArgs(), data, null, null, null);
    assertThat(WindowsProcesses.processGetLastError(process)).isEmpty();
  }

  @Test
  public void testRedirect() throws Exception {
    String stdoutFile = System.getenv("TEST_TMPDIR") + "\\stdout_redirect";
    String stderrFile = System.getenv("TEST_TMPDIR") + "\\stderr_redirect";

    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-one", "E-two"), null, null, stdoutFile, stderrFile);
    assertThat(process).isGreaterThan(0L);
    assertNoProcessError();
    assertThat(WindowsProcesses.waitFor(process, -1)).isEqualTo(0);
    WindowsProcesses.getExitCode(process);
    assertNoProcessError();
    byte[] stdout = Files.readAllBytes(Paths.get(stdoutFile));
    byte[] stderr = Files.readAllBytes(Paths.get(stderrFile));
    assertThat(new String(stdout, UTF_8)).isEqualTo("one");
    assertThat(new String(stderr, UTF_8)).isEqualTo("two");
  }

  @Test
  public void testRedirectToSameFile() throws Exception {
    String file = System.getenv("TEST_TMPDIR") + "\\captured_";

    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-one", "E-two"), null, null, file, file);
    assertThat(process).isGreaterThan(0L);
    assertNoProcessError();
    assertThat(WindowsProcesses.waitFor(process, -1)).isEqualTo(0);
    WindowsProcesses.getExitCode(process);
    assertNoProcessError();
    byte[] bytes = Files.readAllBytes(Paths.get(file));
    assertThat(new String(bytes, UTF_8)).isEqualTo("onetwo");
  }

  @Test
  public void testReadingFromRedirectedStreams() throws Exception {
    String stdoutFile = System.getenv("TEST_TMPDIR") + "\\captured_stdout";
    String stderrFile = System.getenv("TEST_TMPDIR") + "\\captured_stderr";

    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-one", "E-two"), null, null, stdoutFile, stderrFile);
    assertNoProcessError();
    byte[] buf = new byte[1];
    assertThat(readStdout(buf, 0, 1)).isEqualTo(0);
    assertThat(readStderr(buf, 0, 1)).isEqualTo(0);
    WindowsProcesses.waitFor(process, -1);
  }

  @Test
  public void testRedirectedErrorStream() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-one", "E-two"), null, null, null, null, true);
    assertNoProcessError();
    byte[] buf = new byte[6];
    assertThat(readStdout(buf, 0, 3)).isEqualTo(3);
    assertThat(readStdout(buf, 3, 3)).isEqualTo(3);
    assertThat(new String(buf, UTF_8)).isEqualTo("onetwo");
    assertThat(readStderr(buf, 0, 1)).isEqualTo(0);
    WindowsProcesses.waitFor(process, -1);
  }

  @Test
  public void testAppendToExistingFile() throws Exception {
    String stdoutFile = System.getenv("TEST_TMPDIR") + "\\stdout_atef";
    String stderrFile = System.getenv("TEST_TMPDIR") + "\\stderr_atef";
    Path stdout = Paths.get(stdoutFile);
    Path stderr = Paths.get(stderrFile);
    Files.write(stdout, "out1".getBytes(UTF_8));
    Files.write(stderr, "err1".getBytes(UTF_8));

    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("O-out2", "E-err2"), null, null, stdoutFile, stderrFile);
    assertNoProcessError();
    WindowsProcesses.waitFor(process, -1);
    WindowsProcesses.getExitCode(process);
    assertNoProcessError();
    byte[] stdoutBytes = Files.readAllBytes(Paths.get(stdoutFile));
    byte[] stderrBytes = Files.readAllBytes(Paths.get(stderrFile));
    assertThat(new String(stdoutBytes, UTF_8)).isEqualTo("out1out2");
    assertThat(new String(stderrBytes, UTF_8)).isEqualTo("err1err2");
  }

  @Test
  public void testCwd() throws Exception {
    String dir1 = System.getenv("TEST_TMPDIR") + "/dir1";
    new File(dir1).mkdir();

    process =
        WindowsProcesses.createProcess(mockBinary, mockArgs("O."), null, dir1, null, null);
    assertNoProcessError();
    byte[] buf = new byte[1024]; // Windows MAX_PATH is 260, but whatever
    int len = readStdout(buf, 0, 1024);
    assertNoProcessError();
    assertThat(new String(buf, 0, len, UTF_8).replace("\\", "/")).isEqualTo(dir1);
  }

  @Test
  public void testTimeout() throws Exception {
    process =
        WindowsProcesses.createProcess(
            mockBinary, mockArgs("W5", "X0"), null, null, null, null);
    assertThat(WindowsProcesses.waitFor(process, 1000)).isEqualTo(1);
  }
}
