// Copyright 2019 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.bazel.rules.ninja;

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

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.devtools.build.lib.bazel.rules.ninja.file.GenericParsingException;
import com.google.devtools.build.lib.bazel.rules.ninja.parser.NinjaRule;
import com.google.devtools.build.lib.bazel.rules.ninja.parser.NinjaRuleVariable;
import com.google.devtools.build.lib.bazel.rules.ninja.parser.NinjaTarget;
import com.google.devtools.build.lib.bazel.rules.ninja.parser.NinjaVariableValue;
import com.google.devtools.build.lib.bazel.rules.ninja.pipeline.NinjaPipeline;
import com.google.devtools.build.lib.concurrent.ExecutorUtil;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.DigestHashFunction.DefaultHashFunctionNotSetException;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.JavaIoFileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link com.google.devtools.build.lib.bazel.rules.ninja.pipeline.NinjaPipeline}. */
@RunWith(JUnit4.class)
public class NinjaPipelineTest {
  private static class Tester {
    private final Path dir;
    private final ListeningExecutorService service;

    Tester() throws IOException, DefaultHashFunctionNotSetException {
      service =
          MoreExecutors.listeningDecorator(
              Executors.newFixedThreadPool(
                  25,
                  new ThreadFactoryBuilder()
                      .setNameFormat(NinjaPipelineTest.class.getSimpleName() + "-%d")
                      .build()));
      java.nio.file.Path tmpDir = Files.createTempDirectory("test");
      dir = new JavaIoFileSystem().getPath(tmpDir.toString());
    }

    ListeningExecutorService getService() {
      return service;
    }

    Path writeTmpFile(String name, String... lines) throws IOException {
      Path path = dir.getRelative(name);
      if (lines.length > 0) {
        FileSystemUtils.writeContent(
            path, String.join("\n", lines).getBytes(StandardCharsets.ISO_8859_1));
      } else {
        FileSystemUtils.createEmptyFile(path);
      }
      return path;
    }

    public void tearDown() throws IOException {
      ExecutorUtil.interruptibleShutdown(service);
      dir.deleteTree();
    }
  }

  private Tester tester;

  @Before
  public void setUp() throws Exception {
    try {
      DigestHashFunction.setDefault(DigestHashFunction.SHA256);
    } catch (DigestHashFunction.DefaultAlreadySetException e) {
      // Do nothing.
    }
    tester = new Tester();
  }

  @After
  public void tearDown() throws Exception {
    tester.tearDown();
  }

  @Test
  public void testOneFilePipeline() throws Exception {
    Path vfsPath =
        tester.writeTmpFile(
            "test.ninja",
            "rule r1",
            "  command = c $in $out",
            "build t1: r1 in1 in2",
            "build t2: r1 in3");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(), tester.getService(), ImmutableList.of(), "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    checkTargets(targets);
  }

  @Test
  public void testOneFilePipelineWithNewlines() throws Exception {
    Path vfsPath =
        tester.writeTmpFile(
            "test.ninja",
            "",
            "",
            "",
            "",
            "rule r1",
            "  command = c $in $out",
            "",
            "",
            "",
            "build t1: r1 in1 in2",
            "",
            "",
            "",
            "build t2: r1 in3",
            "");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(), tester.getService(), ImmutableList.of(), "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    checkTargets(targets);
  }

  @Test
  public void testWithIncluded() throws Exception {
    Path vfsPath =
        tester.writeTmpFile(
            "test.ninja", "rule r1", "  command = c $in $out", "include child.ninja");
    Path childFile = tester.writeTmpFile("child.ninja", "build t1: r1 in1 in2", "build t2: r1 in3");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(),
            tester.getService(),
            ImmutableList.of(childFile),
            "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    checkTargets(targets);
  }

  @Test
  public void testComputedSubNinja() throws Exception {
    Path vfsPath =
        tester.writeTmpFile(
            "test.ninja",
            "subfile=child",
            "rule r1",
            "  command = c $in $out",
            "include ${subfile}.ninja");
    Path childFile = tester.writeTmpFile("child.ninja", "build t1: r1 in1 in2", "build t2: r1 in3");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(),
            tester.getService(),
            ImmutableList.of(childFile),
            "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    checkTargets(targets);
  }

  @Test
  public void testComputedDeeplyIncluded() throws Exception {
    Path vfsPath =
        tester.writeTmpFile(
            "test.ninja",
            "subfile=child",
            "subninja_file=sub",
            "rule r1",
            "  command = c $in $out",
            "include ${subfile}.ninja",
            "build t1: r1 ${top_scope_var} in2");
    Path childFile =
        tester.writeTmpFile(
            "child.ninja",
            "top_scope_var=in1",
            "var_for_sub=in3",
            "subninja ${subninja_file}.ninja");
    Path subFile = tester.writeTmpFile("sub.ninja", "build t2: r1 ${var_for_sub}");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(),
            tester.getService(),
            ImmutableList.of(childFile, subFile),
            "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    checkTargets(targets);
  }

  @Test
  public void testEmptyFile() throws Exception {
    Path vfsPath = tester.writeTmpFile("test.ninja");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(), tester.getService(), ImmutableList.of(), "ninja_target");
    List<NinjaTarget> targets = pipeline.pipeline(vfsPath);
    assertThat(targets).isEmpty();
  }

  @Test
  public void testIncludedNinjaFileIsNotDeclared() throws Exception {
    Path vfsPath = tester.writeTmpFile("test.ninja", "include subfile.ninja");
    GenericParsingException exception =
        assertThrows(
            GenericParsingException.class,
            () ->
                new NinjaPipeline(
                        vfsPath.getParentDirectory(),
                        tester.getService(),
                        ImmutableList.of(),
                        "ninja_target")
                    .pipeline(vfsPath));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Ninja file requested from 'test.ninja' "
                + "not declared in 'srcs' attribute of 'ninja_target'.");
  }

  @Test
  public void testIncludeCycle() throws Exception {
    Path vfsPath = tester.writeTmpFile("test.ninja", "include one.ninja");
    Path oneFile = tester.writeTmpFile("one.ninja", "include two.ninja");
    Path twoFile = tester.writeTmpFile("two.ninja", "include one.ninja");
    NinjaPipeline pipeline =
        new NinjaPipeline(
            vfsPath.getParentDirectory(),
            tester.getService(),
            ImmutableList.of(oneFile, twoFile),
            "ninja_target");
    GenericParsingException exception =
        assertThrows(GenericParsingException.class, () -> pipeline.pipeline(vfsPath));
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo(
            "Detected cycle or duplicate inclusion in Ninja files dependencies, "
                + "including 'one.ninja'.");
  }

  @Test
  public void testBigFile() throws Exception {
    String[] lines = new String[1000];
    for (int i = 0; i < lines.length - 1; i++) {
      lines[i] = "rule rule" + i + "\n command = echo 'Hello' > ${out}";
    }
    lines[999] = "build out: rule1";
    Path path = tester.writeTmpFile("big_file.ninja", lines);
    NinjaPipeline pipeline =
        new NinjaPipeline(
            path.getParentDirectory(), tester.getService(), ImmutableList.of(), "ninja_target");
    // Test specifically that all manipulations with connecting buffers are working fine:
    // for that, have relatively long file and small buffer size.
    pipeline.setReadBlockSize(100);
    List<NinjaTarget> targets = pipeline.pipeline(path);
    assertThat(targets).hasSize(1);
    Map<String, List<Pair<Integer, NinjaRule>>> rules = targets.get(0).getScope().getRules();
    assertThat(rules).hasSize(999);
    assertThat(rules.get("rule1")).hasSize(1);
    NinjaVariableValue expectedValue =
        NinjaVariableValue.builder().addText("echo 'Hello' > ").addVariable("out").build();
    assertThat(
            rules
                .get("rule1")
                .get(0)
                .getSecond()
                .getVariables()
                .get(NinjaRuleVariable.COMMAND)
                .getRawText())
        .isEqualTo(expectedValue.getRawText());
  }

  private static void checkTargets(List<NinjaTarget> targets) {
    assertThat(targets).hasSize(2);
    for (NinjaTarget target : targets) {
      if (target.getAllOutputs().contains(PathFragment.create("t1"))) {
        assertThat(target.getAllInputs())
            .containsExactly(PathFragment.create("in1"), PathFragment.create("in2"));
      } else if (target.getAllOutputs().contains(PathFragment.create("t2"))) {
        assertThat(target.getAllInputs()).containsExactly(PathFragment.create("in3"));
      } else {
        fail();
      }
    }
  }
}
