// Copyright 2021 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.buildtool;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.server.FailureDetails;
import com.google.devtools.build.lib.skyframe.DetailedException;
import com.google.devtools.build.lib.util.io.RecordingOutErr;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for Starlark "unused inputs list" functionality on failures caused by unused inputs. */
@RunWith(TestParameterInjector.class)
public final class UnusedInputsFailureIntegrationTest extends BuildIntegrationTestCase {

  @TestParameter private boolean keepGoing;

  @Before
  public void setOptions() {
    addOptions("--keep_going=" + keepGoing);
  }

  @Test
  public void incrementalFailureOnUnusedInput() throws Exception {
    RecordingBugReporter bugReporter = recordBugReportsAndReinitialize();
    write(
        "foo/pruning.bzl",
        """
        def _impl(ctx):
            inputs = ctx.attr.inputs.files
            output = ctx.actions.declare_file(ctx.label.name + ".out")
            unused_file = ctx.actions.declare_file(ctx.label.name + ".unused")
            ctx.actions.run(
                # Make sure original inputs are one level down,
                # so 'leaf unrolling' doesn't get them
                inputs = depset(transitive = [ctx.attr.filler.files, inputs]),
                outputs = [output, unused_file],
                arguments = [output.path, unused_file.path] + [f.path for f in inputs.to_list()],
                executable = ctx.executable.executable,
                unused_inputs_list = unused_file,
            )
            return DefaultInfo(files = depset([output]))

        build_rule = rule(
            attrs = {
                "inputs": attr.label(allow_files = True),
                "filler": attr.label(allow_files = True),
                "executable": attr.label(executable = True, allow_files = True, cfg = "exec"),
            },
            implementation = _impl,
        )
        """);
    write("foo/unused.sh", "touch $1", "shift", "unused=$1", "shift", "echo $@ > $unused")
        .setExecutable(true);
    write("foo/gen_run.sh", "true").setExecutable(true);
    write("foo/filler");
    write(
        "foo/BUILD",
        """
        load("//foo:pruning.bzl", "build_rule")

        build_rule(
            name = "foo",
            executable = ":unused.sh",
            filler = ":filler",
            inputs = ":in",
        )

        genrule(
            name = "gen",
            outs = ["in"],
            cmd = "$(location :gen_run.sh) && touch $@",
            tools = [":gen_run.sh"],
        )
        """);
    buildTarget("//foo:foo");
    bugReporter.assertNoExceptions();

    write("foo/gen_run.sh", "false");
    if (keepGoing) {
      buildTarget("//foo:foo");
      bugReporter.assertNoExceptions();
    } else {
      RecordingOutErr outErr = new RecordingOutErr();
      this.outErr = outErr;
      BuildFailedException e = assertThrows(BuildFailedException.class, () -> buildTarget("//foo"));
      assertThat(e.getDetailedExitCode().getFailureDetail())
          .comparingExpectedFieldsOnly()
          .isEqualTo(
              FailureDetails.FailureDetail.newBuilder()
                  .setExecution(
                      FailureDetails.Execution.newBuilder()
                          .setCode(FailureDetails.Execution.Code.UNEXPECTED_EXCEPTION)
                          .build())
                  .build());
      assertThat(outErr.errAsLatin1()).contains("Executing genrule //foo:gen failed");
      Throwable cause = bugReporter.getFirstCause();
      assertThat(cause).hasMessageThat().contains("Error evaluating artifact nested set");
      assertThat(cause).hasMessageThat().contains("foo/gen_run.sh");
    }
  }

  /**
   * Regression test for b/185998331.
   *
   * <p>The action graph is:
   *
   * <pre>
   *            top [consume.out] -> [top.out]
   *                           |
   *           consume [consume.sh, prune.out] -> [consume.out]
   *                           |
   *      prune [prune.sh, [bad.out, good.out]] -> [prune.out, unused_list]
   *                   /                \
   *     bad [bad.sh] -> [bad.out]     good [] -> [good.out]
   * </pre>
   *
   * where 'prune' reports 'bad' as an unused input. On the first build, 'consume' fails. On the
   * second build, 'bad' fails. If the error is not handled correctly by 'prune', 'top' won't know
   * that 'consume' is unavailable.
   */
  @Test
  public void incrementalFailureOnUnusedInput_downstreamInputNotReady() throws Exception {
    write(
        "foo/defs.bzl",
        """
        def _example_rule_impl(ctx):
            bad = ctx.actions.declare_file("bad.out")
            ctx.actions.run(
                outputs = [bad],
                executable = ctx.executable.bad_sh,
                arguments = [bad.path],
            )

            good = ctx.actions.declare_file("good.out")
            ctx.actions.run_shell(outputs = [good], command = "touch %s" % good.path)

            unused_list = ctx.actions.declare_file("unused_list")
            prune = ctx.actions.declare_file("prune.out")
            ctx.actions.run(
                outputs = [prune, unused_list],
                inputs = [bad, good],
                unused_inputs_list = unused_list,
                executable = ctx.executable.prune_sh,
                arguments = [prune.path, unused_list.path, bad.path],
            )

            consume = ctx.actions.declare_file("consume.out")
            ctx.actions.run(
                outputs = [consume],
                inputs = [prune],
                executable = ctx.executable.consume_sh,
                arguments = [consume.path],
            )

            top = ctx.actions.declare_file("top.out")
            ctx.actions.run_shell(
                outputs = [top],
                inputs = [consume],
                command = "touch %s" % top.path,
            )
            return DefaultInfo(files = depset([top]))

        example_rule = rule(
            implementation = _example_rule_impl,
            attrs = {
                "bad_sh": attr.label(
                    executable = True,
                    allow_single_file = True,
                    cfg = "exec",
                    default = "bad.sh",
                ),
                "prune_sh": attr.label(
                    executable = True,
                    allow_single_file = True,
                    cfg = "exec",
                    default = "prune.sh",
                ),
                "consume_sh": attr.label(
                    executable = True,
                    allow_single_file = True,
                    cfg = "exec",
                    default = "consume.sh",
                ),
            },
        )
        """);
    write(
        "foo/BUILD",
        """
        load(":defs.bzl", "example_rule")

        example_rule(name = "example")
        """);
    write("foo/bad.sh", "#!/bin/bash", "touch $1").setExecutable(true);
    write("foo/prune.sh", "#!/bin/bash", "touch $1 && echo $3 > $2").setExecutable(true);
    write("foo/consume.sh", "#!/bin/bash", "exit 1").setExecutable(true);
    assertThrows(BuildFailedException.class, () -> buildTarget("//foo:example"));
    assertContainsError("Action foo/consume.out failed");

    write("foo/bad.sh", "#!/bin/bash", "exit 1").setExecutable(true);
    write("foo/consume.sh", "#!/bin/bash", "touch $@").setExecutable(true);

    if (keepGoing) {
      buildTarget("//foo:example");
    } else {
      assertThrows(BuildFailedException.class, () -> buildTarget("//foo:example"));
      assertContainsError("Action foo/bad.out failed");
    }
  }

  @Test
  public void incrementalUnusedSymlinkCycle() throws Exception {
    RecordingBugReporter bugReporter = recordBugReportsAndReinitialize();
    write(
        "foo/pruning.bzl",
        """
        def _impl(ctx):
            inputs = ctx.attr.inputs.files
            output = ctx.actions.declare_file(ctx.label.name + ".out")
            unused_inputs_list = ctx.actions.declare_file(ctx.label.name + ".unused")
            arguments = [output.path, unused_inputs_list.path]
            for input in inputs.to_list():
                arguments += [input.path]
            ctx.actions.run(
                inputs = inputs,
                outputs = [output, unused_inputs_list],
                arguments = arguments,
                executable = ctx.executable.executable,
                unused_inputs_list = unused_inputs_list,
            )
            return DefaultInfo(files = depset([output]))

        build_rule = rule(
            attrs = {
                "inputs": attr.label(allow_files = True),
                "executable": attr.label(executable = True, allow_files = True, cfg = "exec"),
            },
            implementation = _impl,
        )
        """);
    Path unusedSh =
        write("foo/all_unused.sh", "touch $1", "shift", "unused=$1", "shift", "echo $@ > $unused");
    unusedSh.setExecutable(true);
    Path inPath = write("foo/in");
    write(
        "foo/BUILD",
        """
        load("//foo:pruning.bzl", "build_rule")

        build_rule(
            name = "prune",
            executable = ":all_unused.sh",
            inputs = ":in",
        )
        """);
    buildTarget("//foo:prune");
    bugReporter.assertNoExceptions();

    inPath.delete();
    inPath.createSymbolicLink(PathFragment.create("in"));
    if (keepGoing) {
      buildTarget("//foo:prune");
      bugReporter.assertNoExceptions();
    } else {
      RecordingOutErr outErr = new RecordingOutErr();
      this.outErr = outErr;
      BuildFailedException e =
          assertThrows(BuildFailedException.class, () -> buildTarget("//foo:prune"));
      assertDetailedExitCodeIsSourceIOFailure(e);
      Throwable cause = bugReporter.getFirstCause();
      assertDetailedExitCodeIsSourceIOFailure(cause);
      assertThat(cause).hasMessageThat().isEqualTo("error reading file '//foo:in': Symlink cycle");
      assertThat(outErr.errAsLatin1()).contains("error reading file '//foo:in': Symlink cycle");
    }
  }

  private static final FailureDetails.FailureDetail SOURCE_IO_FAILURE =
      FailureDetails.FailureDetail.newBuilder()
          .setExecution(
              FailureDetails.Execution.newBuilder()
                  .setCode(FailureDetails.Execution.Code.SOURCE_INPUT_IO_EXCEPTION))
          .build();

  private static void assertDetailedExitCodeIsSourceIOFailure(Throwable exception) {
    assertThat(exception).isInstanceOf(DetailedException.class);
    assertThat(((DetailedException) exception).getDetailedExitCode().getFailureDetail())
        .comparingExpectedFieldsOnly()
        .isEqualTo(SOURCE_IO_FAILURE);
  }

  @Test
  public void incrementalUnusedDanglingSymlink() throws Exception {
    write(
        "foo/pruning.bzl",
        """
        def _impl(ctx):
            inputs = ctx.attr.inputs.files
            output = ctx.actions.declare_file(ctx.label.name + ".out")
            unused_inputs_list = ctx.actions.declare_file(ctx.label.name + ".unused")
            arguments = [output.path, unused_inputs_list.path]
            for input in inputs.to_list():
                arguments += [input.path]
            ctx.actions.run(
                inputs = inputs,
                outputs = [output, unused_inputs_list],
                arguments = arguments,
                executable = ctx.executable.executable,
                unused_inputs_list = unused_inputs_list,
            )
            return DefaultInfo(files = depset([output]))

        build_rule = rule(
            attrs = {
                "inputs": attr.label(allow_files = True),
                "executable": attr.label(executable = True, allow_files = True, cfg = "exec"),
            },
            implementation = _impl,
        )
        """);
    Path unusedSh =
        write("foo/all_unused.sh", "touch $1", "shift", "unused=$1", "shift", "echo $@ > $unused");
    unusedSh.setExecutable(true);
    Path inPath = write("foo/in");
    write(
        "foo/BUILD",
        """
        load("//foo:pruning.bzl", "build_rule")

        build_rule(
            name = "prune",
            executable = ":all_unused.sh",
            inputs = ":in",
        )
        """);
    buildTarget("//foo:prune");
    inPath.delete();
    inPath.createSymbolicLink(PathFragment.create("nope"));
    buildTarget("//foo:prune");
  }
}
