// Copyright 2022 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.skyframe.rewinding;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;

import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.includescanning.IncludeScanningModule;
import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.testutil.ActionEventRecorder;
import com.google.testing.junit.testparameterinjector.TestParameter;
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Tests for action rewinding on non-incremental builds. */
// TODO(b/228090759): Add back actionFromPreviousBuildReevaluated when incrementality is supported.
@RunWith(TestParameterInjector.class)
public final class RewindingTest extends BuildIntegrationTestCase {

  @TestParameter private boolean keepGoing;

  private final ActionEventRecorder actionEventRecorder = new ActionEventRecorder();
  private final RewindingTestsHelper helper = new RewindingTestsHelper(this, actionEventRecorder);

  @Override
  protected BlazeRuntime.Builder getRuntimeBuilder() throws Exception {
    return super.getRuntimeBuilder()
        .addBlazeModule(new IncludeScanningModule())
        .addBlazeModule(helper.makeControllableActionStrategyModule("standalone"));
  }

  @Override
  protected void setupOptions() throws Exception {
    super.setupOptions();
    addOptions(
        "--spawn_strategy=standalone",
        "--notrack_incremental_state",
        "--nouse_action_cache",
        "--rewind_lost_inputs",
        "--features=cc_include_scanning",
        "--experimental_remote_include_extraction_size_threshold=0",
        "--keep_going=" + keepGoing);
    runtimeWrapper.registerSubscriber(actionEventRecorder);
  }

  /**
   * Skips test cases that cannot run with bazel.
   *
   * <p>{@link BuildIntegrationTestCase} currently does not support CPP compilation on bazel.
   */
  // TODO(b/195425240): Remove once CPP compilation on bazel is supported. Assumptions that
  // generated headers are always under k8-opt will need to be relaxed to support other platforms.
  private static void skipIfBazel() {
    assume().that(AnalysisMock.get().isThisBazel()).isFalse();
  }

  @Test
  public void noLossSmokeTest() throws Exception {
    helper.runNoLossSmokeTest();
  }

  @Test
  public void buildingParentFoundUndoneChildNotToleratedWithoutRewinding() throws Exception {
    helper.runBuildingParentFoundUndoneChildNotToleratedWithoutRewinding();
  }

  @Test
  public void dependentActionsReevaluated() throws Exception {
    helper.runDependentActionsReevaluated_spawnFailed();
  }

  @Test
  public void inputDiscoveringActionNoticesMissingDep() throws Exception {
    skipIfBazel();
    helper.runInputDiscoveringActionNoticesMissingDep();
  }

  @Test
  public void multipleLostInputsForRewindPlan() throws Exception {
    helper.runMultipleLostInputsForRewindPlan();
  }

  @Test
  public void multiplyLosingInputsFails() throws Exception {
    helper.runMultiplyLosingInputsFails();
    assertOutputForRule2NotCreated();
  }

  @Test
  public void interruptedDuringRewindStopsNormally() throws Exception {
    helper.runInterruptedDuringRewindStopsNormally();
    assertOutputForRule2NotCreated();
  }

  @Test
  public void failureDuringRewindStopsNormally() throws Exception {
    helper.runFailureDuringRewindStopsNormally();
    assertOutputForRule2NotCreated();
  }

  /**
   * Because this test infrastructure allows builds to write outputs to the filesystem, these
   * "fail"/"stops normally" tests can assert that the build's output file was not written.
   */
  private void assertOutputForRule2NotCreated() throws Exception {
    Artifact output =
        Iterables.getOnlyElement(
            getFilesToBuild(getExistingConfiguredTarget("//test:rule2")).toList());
    assertThat(output.getPath().exists()).isFalse();
  }

  @Test
  public void intermediateActionRewound() throws Exception {
    helper.runIntermediateActionRewound();
  }

  @Test
  public void chainOfActionsRewound() throws Exception {
    helper.runChainOfActionsRewound();
  }

  @Test
  public void nondeterministicActionRewound() throws Exception {
    helper.runNondeterministicActionRewound();
  }

  @Test
  public void parallelTrackSharedActionsRewound() throws Exception {
    helper.runParallelTrackSharedActionsRewound();
  }

  @Test
  public void treeFileArtifactRewound() throws Exception {
    skipIfBazel();
    helper.runTreeFileArtifactRewound_spawnFailed();
  }

  @Test
  public void treeArtifactRewound_allFilesLost() throws Exception {
    skipIfBazel();
    helper.runTreeArtifactRewound_allFilesLost_spawnFailed();
  }

  @Test
  public void treeArtifactRewound_oneFileLost() throws Exception {
    skipIfBazel();
    helper.runTreeArtifactRewound_oneFileLost_spawnFailed();
  }

  @Test
  public void generatedRunfilesRewound_allFilesLost() throws Exception {
    helper.runGeneratedRunfilesRewound_allFilesLost_spawnFailed();
  }

  @Test
  public void generatedRunfilesRewound_oneFileLost() throws Exception {
    helper.runGeneratedRunfilesRewound_oneFileLost_spawnFailed();
  }

  @Test
  public void dupeDirectAndRunfilesDependencyRewound() throws Exception {
    helper.runDupeDirectAndRunfilesDependencyRewound_spawnFailed();
  }

  @Test
  public void treeInRunfilesRewound() throws Exception {
    helper.runTreeInRunfilesRewound_spawnFailed();
  }

  @Test
  public void inputsFromSameGeneratingActionSplitAmongNestedSetChildren() throws Exception {
    helper.runInputsFromSameGeneratingActionSplitAmongNestedSetChildren();
  }

  @Test
  public void generatedHeaderRewound_lostInInputDiscovery() throws Exception {
    skipIfBazel();
    helper.runGeneratedHeaderRewound_lostInInputDiscovery_spawnFailed();
  }

  @Test
  public void generatedHeaderRewound_lostInActionExecution() throws Exception {
    skipIfBazel();
    helper.runGeneratedHeaderRewound_lostInActionExecution_spawnFailed();
  }

  @Test
  public void generatedTransitiveHeaderRewound_lostInInputDiscovery() throws Exception {
    skipIfBazel();
    helper.runGeneratedTransitiveHeaderRewound_lostInInputDiscovery_spawnFailed();
  }

  @Test
  public void generatedTransitiveHeaderRewound_lostInActionExecution() throws Exception {
    skipIfBazel();
    helper.runGeneratedTransitiveHeaderRewound_lostInActionExecution_spawnFailed();
  }

  @Test
  public void doneToDirtyDepForNodeInError() throws Exception {
    helper.runDoneToDirtyDepForNodeInError();
  }
}
