// 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.runtime;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionProgressReceiverAvailableEvent;
import com.google.devtools.build.lib.clock.Clock;
import com.google.devtools.build.lib.pkgcache.LoadingPhaseCompleteEvent;
import com.google.devtools.build.lib.skyframe.ConfigurationPhaseStartedEvent;
import com.google.devtools.build.lib.skyframe.LoadingPhaseStartedEvent;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.io.AnsiTerminalWriter;
import com.google.devtools.build.lib.util.io.PositionAwareAnsiTerminalWriter;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.time.Instant;

/** Tracks the state of Skymeld builds and determines what to display at each state in the UI. */
final class SkymeldUiStateTracker extends UiStateTracker {

  enum BuildStatus {
    // We explicitly define a starting status, which can be used to determine what to display in
    // cases before the build has started.
    BUILD_NOT_STARTED,
    COMPUTING_MAIN_REPO_MAPPING,
    BUILD_STARTED,
    TARGET_PATTERN_PARSING,
    LOADING_COMPLETE,
    CONFIGURATION, // Analysis with configuration.
    // The order of the AnalysisCompleteEvent and ExecutionProgressReceiverAvailableEvent is not
    // certain, this splits the possible paths of the change in BuildStatus into two.
    ANALYSIS_COMPLETE, // After analysis but before execution.
    ANALYSIS_AND_EXECUTION, // During analysis and execution.
    EXECUTION, // Only execution.
    BUILD_COMPLETED;
  }

  @VisibleForTesting BuildStatus buildStatus = BuildStatus.BUILD_NOT_STARTED;

  SkymeldUiStateTracker(Clock clock, int targetWidth) {
    super(clock, targetWidth);
  }

  SkymeldUiStateTracker(Clock clock) {
    super(clock);
  }

  /**
   * Main method that writes the progress of the build.
   *
   * @param rawTerminalWriter used to write to the terminal.
   * @param shortVersion whether to write a short version of the output.
   * @param timestamp null if the UiOptions specifies not to show timestamps.
   * @throws IOException when attempting to write to the terminal writer.
   */
  @Override
  synchronized void writeProgressBar(
      AnsiTerminalWriter rawTerminalWriter, boolean shortVersion, String timestamp)
      throws IOException {
    PositionAwareAnsiTerminalWriter terminalWriter =
        new PositionAwareAnsiTerminalWriter(rawTerminalWriter);
    if (timestamp != null) {
      terminalWriter.append(timestamp);
    }
    switch (buildStatus) {
      case BUILD_NOT_STARTED:
        return;
      case COMPUTING_MAIN_REPO_MAPPING:
        writeBaseProgress("Computing main repo mapping", "", terminalWriter);
        break;
      case BUILD_STARTED:
        writeBaseProgress("Loading", "", terminalWriter);
        break;
      case TARGET_PATTERN_PARSING:
        writeLoadingAnalysisPhaseProgress("Loading", "", terminalWriter, false);
        break;
      case LOADING_COMPLETE:
      case CONFIGURATION:
        writeLoadingAnalysisPhaseProgress(
            "Analyzing", additionalMessage, terminalWriter, shortVersion);
        break;
      case ANALYSIS_COMPLETE:
        // Currently, regular Blaze does not add additional information in this phase, and this is
        // left empty on purpose to mimic the same behavior.
        break;
      case ANALYSIS_AND_EXECUTION:
        writeLoadingAnalysisPhaseProgress(
            "Analyzing", additionalMessage, terminalWriter, shortVersion);
        terminalWriter.newline();
        writeExecutionProgress(terminalWriter, shortVersion);
        break;
      case EXECUTION:
        writeExecutionProgress(terminalWriter, shortVersion);
        break;
      case BUILD_COMPLETED:
        writeBaseProgress(ok ? "INFO" : "FAILED", additionalMessage, terminalWriter);
        break;
    }

    if (!shortVersion) {
      reportOnDownloads(terminalWriter);
      maybeReportActiveUploadsOrDownloads(terminalWriter);
      maybeReportBepTransports(terminalWriter);
    }
  }

  void writeBaseProgress(
      String status, String message, PositionAwareAnsiTerminalWriter terminalWriter)
      throws IOException {
    if (ok) {
      terminalWriter.okStatus();
    } else {
      terminalWriter.failStatus();
    }
    terminalWriter.append(status + ":").normal().append(" " + message);
  }

  void writeLoadingAnalysisPhaseProgress(
      String status,
      String message,
      PositionAwareAnsiTerminalWriter terminalWriter,
      boolean shortVersion)
      throws IOException {
    writeBaseProgress(status, message, terminalWriter);

    if (packageProgressReceiver != null) {
      Pair<String, String> progress = packageProgressReceiver.progressState();
      String analysisProgress = progress.getFirst();

      if (configuredTargetProgressReceiver != null) {
        analysisProgress += ", " + configuredTargetProgressReceiver.getProgressString();
      }

      if (message.isEmpty()) {
        terminalWriter.append(analysisProgress);
      } else {
        terminalWriter.append(" (" + analysisProgress + ")");
      }
      if (!progress.getSecond().isEmpty() && !shortVersion) {
        terminalWriter.newline().append("    " + progress.getSecond());
      }
    }
  }

  @Override
  void mainRepoMappingComputationStarted() {
    buildStatus = BuildStatus.COMPUTING_MAIN_REPO_MAPPING;
  }

  @Override
  void buildStarted() {
    buildStatus = BuildStatus.BUILD_STARTED;
  }

  @Override
  void loadingStarted(LoadingPhaseStartedEvent event) {
    buildStatus = BuildStatus.TARGET_PATTERN_PARSING;
    packageProgressReceiver = event.getPackageProgressReceiver();
  }

  @Override
  void loadingComplete(LoadingPhaseCompleteEvent event) {
    buildStatus = BuildStatus.LOADING_COMPLETE;
    int labelsCount = event.getLabels().size();
    if (labelsCount == 1) {
      additionalMessage = "target " + Iterables.getOnlyElement(event.getLabels());
    } else {
      additionalMessage = labelsCount + " targets";
    }
    mainRepositoryMapping = event.getMainRepositoryMapping();
  }

  @Override
  void configurationStarted(ConfigurationPhaseStartedEvent event) {
    buildStatus = BuildStatus.CONFIGURATION;
    configuredTargetProgressReceiver = event.getConfiguredTargetProgressReceiver();
  }

  /**
   * Make the state tracker aware of the fact that the analysis has finished. Return a summary of
   * the work done in the analysis phase.
   */
  @Override
  @CanIgnoreReturnValue
  synchronized String analysisComplete() {
    // This is where the path of the BuildStatus splits, the BuildStatus at this point could be
    // either CONFIGURATION or ANALYSIS_AND_EXECUTION.
    buildStatus =
        BuildStatus.CONFIGURATION.equals(buildStatus)
            ? BuildStatus.ANALYSIS_COMPLETE
            : BuildStatus.EXECUTION;
    String workDone = "Analyzed " + additionalMessage;
    if (packageProgressReceiver != null) {
      Pair<String, String> progress = packageProgressReceiver.progressState();
      workDone += " (" + progress.getFirst();
      if (configuredTargetProgressReceiver != null) {
        workDone += ", " + configuredTargetProgressReceiver.getProgressString();
      }
      workDone += ")";
    }
    workDone += ".";
    packageProgressReceiver = null;
    configuredTargetProgressReceiver = null;
    return workDone;
  }

  @Override
  synchronized void progressReceiverAvailable(ExecutionProgressReceiverAvailableEvent event) {
    executionProgressReceiver = event.getExecutionProgressReceiver();
    // This is where the path of the BuildStatus splits, the BuildStatus at this point could be
    // either CONFIGURATION or ANALYSIS_COMPLETE.
    buildStatus =
        BuildStatus.CONFIGURATION.equals(buildStatus)
            ? BuildStatus.ANALYSIS_AND_EXECUTION
            : BuildStatus.EXECUTION;
  }

  @Override
  void buildComplete(BuildCompleteEvent event) {
    buildStatus = BuildStatus.BUILD_COMPLETED;
    buildCompleteAt = Instant.ofEpochMilli(clock.currentTimeMillis());

    if (event.getResult().getSuccess()) {
      int actionsCompleted = this.actionsCompleted.get();
      if (failedTests == 0) {
        additionalMessage =
            "Build completed successfully, "
                + actionsCompleted
                + pluralize(" total action", actionsCompleted);
      } else {
        additionalMessage =
            "Build completed, "
                + failedTests
                + pluralize(" test", failedTests)
                + " FAILED, "
                + actionsCompleted
                + pluralize(" total action", actionsCompleted);
      }
    } else {
      ok = false;
      additionalMessage = "Build did NOT complete successfully";
    }
  }

  @Override
  protected boolean buildCompleted() {
    return BuildStatus.BUILD_COMPLETED.equals(buildStatus);
  }
}
