// Copyright 2014 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.test;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactPathResolver;
import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.view.test.TestStatus.BlazeTestStatus;
import com.google.devtools.build.lib.view.test.TestStatus.TestResultData;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;

/**
 * This is the event passed from the various test strategies to the {@code RecordingTestListener}
 * upon test completion.
 */
@ThreadSafe
@Immutable
public class TestResult implements ExtendedEventHandler.ProgressLike {

  private final TestRunnerAction testAction;
  private final TestResultData data;
  private final boolean cached;
  @Nullable protected final Path execRoot;
  @Nullable private final DetailedExitCode systemFailure;

  /**
   * Construct the TestResult for the given test / status.
   *
   * @param testAction The test that was run.
   * @param data test result protobuffer.
   * @param cached true if this is a locally cached test result.
   * @param execRoot The execution root in which the action was carried out; can be null, in which
   *     case everything depending on the execution root is ignored.
   * @param systemFailure Description of the system failure responsible for the test not succeeding;
   *     null if no such failure occurred
   */
  public TestResult(
      TestRunnerAction testAction,
      TestResultData data,
      boolean cached,
      @Nullable Path execRoot,
      @Nullable DetailedExitCode systemFailure) {
    this.testAction = checkNotNull(testAction);
    this.data = checkNotNull(data);
    this.cached = cached;
    this.execRoot = execRoot;
    this.systemFailure = systemFailure;
  }

  public TestResult(
      TestRunnerAction testAction,
      TestResultData data,
      boolean cached,
      @Nullable DetailedExitCode systemFailure) {
    this(testAction, data, cached, null, systemFailure);
  }

  public static boolean isBlazeTestStatusPassed(BlazeTestStatus status) {
    return status == BlazeTestStatus.PASSED || status == BlazeTestStatus.FLAKY;
  }

  /** Returns the test action. */
  public TestRunnerAction getTestAction() {
    return testAction;
  }

  /**
   * Returns the test log path. Note, that actual log file may no longer correspond to this
   * artifact. Use getActualLogPath() method if you need log location.
   */
  public Path getTestLogPath() {
    Path testLogPath = testAction.getTestLog().getPath();
    // If we have an exec root we'll use its fileSystem
    if (execRoot != null) {
      FileSystem fileSystem = execRoot.getFileSystem();
      return fileSystem.getPath(testLogPath.asFragment());
    }
    return testLogPath;
  }

  /** Returns whether the result was loaded from local action cache. */
  public final boolean isCached() {
    return cached;
  }

  /**
   * Returns the list of locally cached test attempts. This method must only be called if {@link
   * #isCached} returns <code>true</code>.
   */
  public List<TestAttempt> getCachedTestAttempts() {
    Preconditions.checkState(isCached());
    return ImmutableList.of(
        TestAttempt.fromCachedTestResult(
            testAction,
            data,
            1,
            getFiles(),
            BuildEventStreamProtos.TestResult.ExecutionInfo.getDefaultInstance(),
            /*lastAttempt=*/ true));
  }

  /** Returns the coverage data artifact, if available, and null otherwise. */
  public Path getCoverageData() {
    if (data.getHasCoverage()) {
      return testAction.getCoverageData().getPath();
    }
    return null;
  }

  /** Returns the test status artifact. */
  public Artifact getTestStatusArtifact() {
    // these artifacts are used to keep track of the number of pending and completed tests.
    return testAction.getCacheStatusArtifact();
  }

  /**
   * Returns the test name in a user-friendly format. Will generally include the target name and
   * shard number, if applicable.
   */
  public String getTestName() {
    return testAction.getTestName();
  }

  /** Returns the test label. */
  public String getLabel() {
    return Label.print(testAction.getOwner().getLabel());
  }

  /** Returns the test shard number. */
  public int getShardNum() {
    return testAction.getShardNum();
  }

  /**
   * Returns the total number of test shards. 0 means no sharding, whereas 1 means degenerate
   * sharding.
   */
  public int getTotalShards() {
    return testAction.getExecutionSettings().getTotalShards();
  }

  public TestResultData getData() {
    return data;
  }

  /**
   * Returns the description of the system failure responsible for the test not succeeding or {@code
   * null} if no such failure occurred.
   */
  @Nullable
  public DetailedExitCode getSystemFailure() {
    return systemFailure;
  }

  /**
   * Returns the collection of files created by the test, tagged by their name indicating usage
   * (e.g., "test.log").
   */
  private Collection<Pair<String, Path>> getFiles() {
    // TODO(ulfjack): Cache the set of generated files in the TestResultData.
    return testAction.getTestOutputsMapping(ArtifactPathResolver.forExecRoot(execRoot), execRoot);
  }
}
