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

import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap;

import com.google.common.base.Functions;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import com.google.devtools.build.lib.server.FailureDetails.Analysis;
import com.google.devtools.build.lib.server.FailureDetails.Analysis.Code;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.skyframe.SaneAnalysisException;
import com.google.devtools.build.lib.util.DetailedExitCode;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * A mutable action graph. Implementations of this interface must be thread-safe.
 */
public interface MutableActionGraph extends ActionGraph {

  /**
   * Attempts to register the action. If any of the action's outputs already has a generating
   * action, and the two actions are not compatible, then an {@link ActionConflictException} is
   * thrown. The internal data structure may be partially modified when that happens; it is not
   * guaranteed that all potential conflicts are detected, but at least one of them is.
   *
   * <p>For example, take three actions A, B, and C, where A creates outputs a and b, B creates just
   * b, and C creates c and b. There are two potential conflicts in this case, between A and B, and
   * between B and C. Depending on the ordering of calls to this method and the ordering of outputs
   * in the action output lists, either one or two conflicts are detected: if B is registered first,
   * then both conflicts are detected; if either A or C is registered first, then only one conflict
   * is detected.
   */
  void registerAction(ActionAnalysisMetadata action)
      throws ActionConflictException, InterruptedException;

  /** Returns the size of the action graph. */
  int getSize();

  /**
   * This exception is thrown when a conflict between actions is detected. It contains information
   * about the artifact for which the conflict is found, and data about the two conflicting actions
   * and their owners.
   */
  final class ActionConflictException extends Exception implements SaneAnalysisException {

    private final Artifact artifact;
    private final String suffix;

    private static final int MAX_DIFF_ARTIFACTS_TO_REPORT = 5;

    public ActionConflictException(
        ActionKeyContext actionKeyContext,
        Artifact artifact,
        ActionAnalysisMetadata previousAction,
        ActionAnalysisMetadata attemptedAction) {
      super(
          String.format(
              "for %s, previous action: %s, attempted action: %s",
              artifact.prettyPrint(),
              previousAction.prettyPrint(),
              attemptedAction.prettyPrint()));
      this.artifact = artifact;
      this.suffix = debugSuffix(actionKeyContext, attemptedAction, previousAction);
    }

    public Artifact getArtifact() {
      return artifact;
    }

    public void reportTo(EventHandler eventListener) {
      String msg =
          "file '"
              + artifact.prettyPrint()
              + "' is generated by these conflicting actions:\n"
              + suffix;
      eventListener.handle(Event.error(msg));
    }

    @Override
    public DetailedExitCode getDetailedExitCode() {
      return DetailedExitCode.of(
          FailureDetail.newBuilder()
              .setMessage(getMessage())
              .setAnalysis(Analysis.newBuilder().setCode(Code.ACTION_CONFLICT))
              .build());
    }

    private static void addStringDetail(
        StringBuilder sb, String key, String valueA, String valueB) {
      valueA = valueA != null ? valueA : "(null)";
      valueB = valueB != null ? valueB : "(null)";

      sb.append(key).append(": ").append(valueA);
      if (!valueA.equals(valueB)) {
        sb.append(", ").append(valueB);
      }
      sb.append("\n");
    }

    private static void addListDetail(
        StringBuilder sb, String key, Iterable<Artifact> valueA, Iterable<Artifact> valueB) {
      Set<Artifact> diffA = differenceWithoutOwner(valueA, valueB);
      Set<Artifact> diffB = differenceWithoutOwner(valueB, valueA);

      sb.append(key).append(": ");
      if (diffA.isEmpty() && diffB.isEmpty()) {
        sb.append("are equal\n");
      } else {
        if (!diffA.isEmpty()) {
          sb.append(
              "Attempted action contains artifacts not in previous action (first "
                  + MAX_DIFF_ARTIFACTS_TO_REPORT
                  + "): \n");
          prettyPrintArtifactDiffs(sb, diffA);
        }

        if (!diffB.isEmpty()) {
          sb.append(
              "Previous action contains artifacts not in attempted action (first "
                  + MAX_DIFF_ARTIFACTS_TO_REPORT
                  + "): \n");
          prettyPrintArtifactDiffs(sb, diffB);
        }
      }
    }

    /** Returns items in {@code valueA} that are not in {@code valueB}, ignoring the owner. */
    private static Set<Artifact> differenceWithoutOwner(
        Iterable<Artifact> valueA, Iterable<Artifact> valueB) {
      ImmutableSet.Builder<Artifact> diff = new ImmutableSet.Builder<>();

      // Group valueB by exec path for easier checks.
      ImmutableListMultimap<String, Artifact> mapB =
          Streams.stream(valueB)
              .collect(toImmutableListMultimap(Artifact::getExecPathString, Functions.identity()));
      for (Artifact a : valueA) {
        boolean found = false;
        for (Artifact b : mapB.get(a.getExecPathString())) {
          if (a.equalsWithoutOwner(b)) {
            found = true;
            break;
          }
        }
        if (!found) {
          diff.add(a);
        }
      }

      return diff.build();
    }

    /** Pretty print action diffs (at most {@code MAX_DIFF_ARTIFACTS_TO_REPORT} lines). */
    private static void prettyPrintArtifactDiffs(StringBuilder sb, Set<Artifact> diff) {
      for (Artifact artifact : Iterables.limit(diff, MAX_DIFF_ARTIFACTS_TO_REPORT)) {
        sb.append('\t').append(artifact.prettyPrint()).append('\n');
      }
    }

    // See also Actions.canBeShared()
    private static String debugSuffix(
        ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) {
      // Note: the error message reveals to users the names of intermediate files that are not
      // documented in the BUILD language.  This error-reporting logic is rather elaborate but it
      // does help to diagnose some tricky situations.
      StringBuilder sb = new StringBuilder();
      ActionOwner aOwner = a.getOwner();
      ActionOwner bOwner = b.getOwner();
      boolean aNull = aOwner == null;
      boolean bNull = bOwner == null;

      addStringDetail(sb, "Label", aNull ? null : Label.print(aOwner.getLabel()),
          bNull ? null : Label.print(bOwner.getLabel()));
      if ((!aNull && !aOwner.getAspectDescriptors().isEmpty())
          || (!bNull && !bOwner.getAspectDescriptors().isEmpty())) {
        addStringDetail(sb, "Aspects", aspectDescriptor(aOwner), aspectDescriptor(bOwner));
      }
      addStringDetail(sb, "RuleClass", aNull ? null : aOwner.getTargetKind(),
          bNull ? null : bOwner.getTargetKind());
      addStringDetail(sb, "Configuration", aNull ? null : aOwner.getConfigurationChecksum(),
          bNull ? null : bOwner.getConfigurationChecksum());
      addStringDetail(sb, "Mnemonic", a.getMnemonic(), b.getMnemonic());
      try {
        addStringDetail(
            sb,
            "Action key",
            a.getKey(actionKeyContext, /*artifactExpander=*/ null),
            b.getKey(actionKeyContext, /*artifactExpander=*/ null));
      } catch (InterruptedException e) {
        // Only for debugging - skip the key and carry on.
        addStringDetail(sb, "Action key", "<elided due to interrupt>", "<elided due to interrupt>");
        Thread.currentThread().interrupt();
      }

      if ((a instanceof ActionExecutionMetadata) && (b instanceof ActionExecutionMetadata)) {
        addStringDetail(
            sb,
            "Progress message",
            ((ActionExecutionMetadata) a).getProgressMessage(),
            ((ActionExecutionMetadata) b).getProgressMessage());
      }

      Artifact aPrimaryInput = a.getPrimaryInput();
      Artifact bPrimaryInput = b.getPrimaryInput();
      addStringDetail(
          sb,
          "PrimaryInput",
          aPrimaryInput == null ? null : aPrimaryInput.toString(),
          bPrimaryInput == null ? null : bPrimaryInput.toString());
      addStringDetail(
          sb, "PrimaryOutput", a.getPrimaryOutput().toString(), b.getPrimaryOutput().toString());

      // Only add list details if the primary input of A matches the input of B. Otherwise
      // the above information is enough and list diff detail is not needed.
      if ((aPrimaryInput == null && bPrimaryInput == null)
          || (aPrimaryInput != null
              && bPrimaryInput != null
              && aPrimaryInput.toString().equals(bPrimaryInput.toString()))) {
        Artifact aPrimaryOutput = a.getPrimaryOutput();
        Artifact bPrimaryOutput = b.getPrimaryOutput();
        if (!aPrimaryOutput.equalsWithoutOwner(bPrimaryOutput)) {
          sb.append("Primary outputs are different: ")
              .append(System.identityHashCode(aPrimaryOutput))
              .append(", ")
              .append(System.identityHashCode(bPrimaryOutput))
              .append('\n');
        }
        ArtifactOwner aArtifactOwner = aPrimaryOutput.getArtifactOwner();
        ArtifactOwner bArtifactOwner = bPrimaryOutput.getArtifactOwner();
        addStringDetail(
            sb, "Owner information", aArtifactOwner.toString(), bArtifactOwner.toString());
        addListDetail(
            sb,
            "MandatoryInputs",
            a.getMandatoryInputs().toList(),
            b.getMandatoryInputs().toList());
        addListDetail(sb, "Outputs", a.getOutputs(), b.getOutputs());
      }

      return sb.toString();
    }

    @Nullable
    private static String aspectDescriptor(ActionOwner owner) {
      return owner == null
          ? null
          : owner.getAspectDescriptors().stream()
              .map(AspectDescriptor::getDescription)
              .collect(Collectors.joining(",", "[", "]"));
    }
  }
}
