// Copyright 2023 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.producers;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.devtools.build.lib.analysis.DependencyKind.OUTPUT_FILE_RULE_DEPENDENCY;
import static com.google.devtools.build.lib.analysis.DependencyKind.VISIBILITY_DEPENDENCY;
import static com.google.devtools.build.lib.analysis.DependencyResolutionHelpers.getExecutionPlatformLabel;
import static com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition.PATCH_TRANSITION_KEY;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.AnalysisRootCauseEvent;
import com.google.devtools.build.lib.analysis.DependencyKind;
import com.google.devtools.build.lib.analysis.DependencyKind.ToolchainDependencyKind;
import com.google.devtools.build.lib.analysis.DependencyResolutionHelpers;
import com.google.devtools.build.lib.analysis.DependencyResolutionHelpers.ExecutionPlatformResult;
import com.google.devtools.build.lib.analysis.InvalidVisibilityDependencyException;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.ConfigurationTransitionEvent;
import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.TransitionCollector;
import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition.TransitionException;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.causes.LoadingFailedCause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.Aspect;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeTransitionData;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.skyframe.AspectCreationException;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.skyframe.ConfiguredValueCreationException;
import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.state.StateMachine;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.function.Consumer;
import javax.annotation.Nullable;

/**
 * Evaluates dependencies.
 *
 * <p>A dependency is described by a {@link DependencyKind}, a {@link Label} and possibly a list of
 * {@link Aspect}s. This class determines the {@link AttributeConfiguration}, based on the parent's
 * configuration. This may include using the {@link TransitionApplier} to perform an attribute
 * configuration transition.
 *
 * <p>It then delegates computation of the {@link ConfiguredTargetAndData} prerequisite values to
 * {@link PrerequisitesProducer} with the determined configuration(s).
 */
final class DependencyProducer
    implements StateMachine, TransitionApplier.ResultSink, PrerequisitesProducer.ResultSink {
  private static final ConfiguredTargetAndData[] EMPTY_OUTPUT = new ConfiguredTargetAndData[0];

  interface ResultSink extends TransitionCollector {
    /**
     * Accepts dependency values for a given kind and label.
     *
     * <p>Multiple values may occur if there is a split transition.
     *
     * <p>For a skipped dependency, outputs an empty array. See comments in {@link
     * DependencyResolutionHelpers#getExecutionPlatformLabel} for when this happens.
     */
    void acceptDependencyValues(int index, ConfiguredTargetAndData[] values);

    void acceptDependencyError(DependencyError error);

    void acceptDependencyError(MissingEdgeError error);
  }

  // -------------------- Input --------------------
  private final PrerequisiteParameters parameters;
  private final DependencyKind kind;
  private final Label toLabel;
  private final ImmutableList<Aspect> propagatingAspects;

  // -------------------- Output --------------------
  private final ResultSink sink;
  private final int index;

  // -------------------- Internal State --------------------
  private ImmutableMap<String, BuildConfigurationKey> transitionedConfigurations;

  DependencyProducer(
      PrerequisiteParameters parameters,
      DependencyKind kind,
      Label toLabel,
      ImmutableList<Aspect> propagatingAspects,
      ResultSink sink,
      int index) {
    this.parameters = parameters;
    this.kind = checkNotNull(kind);
    this.toLabel = toLabel;
    this.propagatingAspects = propagatingAspects;
    this.sink = sink;
    this.index = index;
  }

  @Override
  public StateMachine step(Tasks tasks) {
    @Nullable Attribute attribute = kind.getAttribute();

    if (kind == VISIBILITY_DEPENDENCY
        || (attribute != null && attribute.getName().equals("visibility"))) {
      // This is always a null transition because visibility targets are not configurable.
      return computePrerequisites(
          AttributeConfiguration.ofVisibility(), /* executionPlatformLabel= */ null);
    }

    // The logic of `DependencyResolutionHelpers.computeDependencyLabels` implies that
    // `parameters.configurationKey()` is non-null for everything that follows.
    BuildConfigurationKey configurationKey = checkNotNull(parameters.configurationKey());

    if (DependencyKind.isToolchain(kind)) {
      // There's no attribute so no attribute transition.

      // This dependency is a toolchain. Its package has not been loaded and therefore we can't
      // determine which aspects and which rule configuration transition we should use, so just
      // use sensible defaults. Not depending on their package makes the error message reporting
      // a missing toolchain a bit better.
      // TODO(lberki): This special-casing is weird. Find a better way to depend on toolchains.
      // This logic needs to stay in sync with the dep finding logic in
      // //third_party/bazel/src/main/java/com/google/devtools/build/lib/analysis/Util.java#findImplicitDeps.
      return computePrerequisites(
          AttributeConfiguration.ofUnary(configurationKey),
          parameters.getExecutionPlatformLabel(
              ((ToolchainDependencyKind) kind).getExecGroupName()));
    }

    if (kind == OUTPUT_FILE_RULE_DEPENDENCY) {
      // There's no attribute so no attribute transition.
      return computePrerequisites(
          AttributeConfiguration.ofUnary(configurationKey), /* executionPlatformLabel= */ null);
    }

    var transitionData =
        AttributeTransitionData.builder()
            .attributes(parameters.attributeMap())
            .analysisData(parameters.starlarkTransitionProvider());
    ExecutionPlatformResult executionPlatformResult =
        getExecutionPlatformLabel(kind, parameters.toolchainContexts(), parameters.aspects());
    switch (executionPlatformResult.kind()) {
      case LABEL:
        transitionData.executionPlatform(executionPlatformResult.label());
        break;
      case NULL_LABEL:
        transitionData.executionPlatform(null);
        break;
      case SKIP:
        sink.acceptDependencyValues(index, EMPTY_OUTPUT);
        return DONE;
      case ERROR:
        return new ExecGroupErrorEmitter(executionPlatformResult.error());
    }
    ConfigurationTransition attributeTransition =
        attribute.getTransitionFactory().create(transitionData.build());
    sink.acceptTransition(kind, toLabel, attributeTransition);
    return new TransitionApplier(
        configurationKey,
        attributeTransition,
        parameters.transitionCache(),
        (TransitionApplier.ResultSink) this,
        parameters.eventHandler(),
        /* runAfter= */ this::processTransitionResult);
  }

  @Override
  public void acceptTransitionedConfigurations(
      ImmutableMap<String, BuildConfigurationKey> transitionedConfigurations) {
    this.transitionedConfigurations = transitionedConfigurations;
  }

  @Override
  public void acceptTransitionError(TransitionException e) {
    sink.acceptDependencyError(
        DependencyError.of(new TransitionException(getMessageWithEdgeTransitionInfo(e), e)));
  }

  @Override
  public void acceptTransitionError(OptionsParsingException e) {
    sink.acceptDependencyError(
        DependencyError.of(
            new OptionsParsingException(
                getMessageWithEdgeTransitionInfo(e), e.getInvalidArgument(), e)));
  }

  private String getMessageWithEdgeTransitionInfo(Throwable e) {
    return String.format(
        "On dependency edge %s (%s) -|%s|-> %s: %s",
        parameters.target().getLabel(),
        parameters.configurationKey().getOptions().shortId(),
        kind.getAttribute().getName(),
        toLabel,
        e.getMessage());
  }

  private StateMachine processTransitionResult(Tasks tasks) {
    if (transitionedConfigurations == null) {
      return DONE; // There was a previously reported error.
    }

    if (isNonconfigurableTargetInSamePackage()) {
      // The target is in the same package as the parent and non-configurable. In the general case
      // loading a child target would defeat Package-based sharding. However, when the target is in
      // the same Package, that concern no longer applies. This optimization means that delegation,
      // and the corresponding creation of additional Skyframe nodes, can be avoided in the very
      // common case of source file dependencies in the same Package.

      // Discards transition keys for patch transitions but keeps them otherwise.
      ImmutableList<String> transitionKeys =
          transitionedConfigurations.size() == 1
                  && transitionedConfigurations.containsKey(PATCH_TRANSITION_KEY)
              ? ImmutableList.of()
              : transitionedConfigurations.keySet().asList();
      return computePrerequisites(
          AttributeConfiguration.ofNullTransitionKeys(transitionKeys),
          /* executionPlatformLabel= */ null);
    }

    String parentChecksum = parameters.configurationKey().getOptionsChecksum();
    for (BuildConfigurationKey configuration : transitionedConfigurations.values()) {
      String childChecksum = configuration.getOptionsChecksum();
      if (!parentChecksum.equals(childChecksum)) {
        parameters
            .eventHandler()
            .post(ConfigurationTransitionEvent.create(parentChecksum, childChecksum));
      }
    }

    if (transitionedConfigurations.size() == 1) {
      BuildConfigurationKey patchedConfiguration =
          transitionedConfigurations.get(PATCH_TRANSITION_KEY);
      if (patchedConfiguration != null) {
        // It was a patch transition or no-op split transition.
        return computePrerequisites(
            AttributeConfiguration.ofUnary(patchedConfiguration),
            /* executionPlatformLabel= */ null);
      }
    }

    return computePrerequisites(
        AttributeConfiguration.ofSplit(transitionedConfigurations),
        /* executionPlatformLabel= */ null);
  }

  private StateMachine computePrerequisites(
      AttributeConfiguration configuration, @Nullable Label executionPlatformLabel) {
    return new PrerequisitesProducer(
        parameters,
        toLabel,
        executionPlatformLabel,
        configuration,
        propagatingAspects,
        (PrerequisitesProducer.ResultSink) this,
        useBaseTargetPrerequisitesSupplier());
  }

  /**
   * Returns true only during aspects evaluation for attribute dependencies not owned by an aspect
   * to enable using the {@link BaseTargetPrerequisitesSupplier} to look up them.
   *
   * <p>Check {@link AspectFunction#baseTargetPrerequisitesSupplier} for more details.
   */
  private boolean useBaseTargetPrerequisitesSupplier() {
    if (parameters.aspects().isEmpty()) {
      return false;
    }

    if (DependencyKind.isAttribute(kind)) {
      if (kind.getOwningAspect() == null) {
        return true;
      }
    }

    return false;
  }

  @Override
  public void acceptPrerequisitesValue(ConfiguredTargetAndData[] value) {
    sink.acceptDependencyValues(index, value);
  }

  @Override
  public void acceptPrerequisitesError(NoSuchThingException error) {
    sink.acceptDependencyError(new MissingEdgeError(kind, toLabel, error));
  }

  @Override
  public void acceptPrerequisitesError(InvalidVisibilityDependencyException error) {
    sink.acceptDependencyError(DependencyError.of(error));
  }

  @Override
  public void acceptPrerequisitesCreationError(ConfiguredValueCreationException error) {
    // Cases where the child target cannot be loaded at all are propagated as
    // `NoSuchThingException`. In some cases, child target loading completes with errors. In that
    // case, the error is propagated as a `ConfiguredValueCreationException` with a
    // `LoadingFailedCause`. Requests parent-side context to be added to such errors by propagating
    // a `MissingEdgeError`.
    for (Cause cause : error.getRootCauses().toList()) {
      if (cause instanceof LoadingFailedCause) {
        var loadingFailed = (LoadingFailedCause) cause;
        if (loadingFailed.getLabel().equals(toLabel)) {
          sink.acceptDependencyError(
              new MissingEdgeError(
                  kind, toLabel, NoSuchTargetException.createForParentPropagation(toLabel)));
        }
      }
    }
  }

  @Override
  public void acceptPrerequisitesAspectError(DependencyEvaluationException error) {
    sink.acceptDependencyError(DependencyError.of(error));
  }

  @Override
  public void acceptPrerequisitesAspectError(AspectCreationException error) {
    sink.acceptDependencyError(DependencyError.of(error));
  }

  private boolean isNonconfigurableTargetInSamePackage() {
    Target parentTarget = parameters.target();
    if (parentTarget.getLabel().getPackageIdentifier().equals(toLabel.getPackageIdentifier())) {
      try {
        Target toTarget = parentTarget.getPackage().getTarget(toLabel.getName());
        if (!toTarget.isConfigurable()) {
          return true;
        }
      } catch (NoSuchTargetException e) {
        parameters
            .transitiveState()
            .addTransitiveCause(new LoadingFailedCause(toLabel, e.getDetailedExitCode()));
        parameters
            .eventHandler()
            .handle(
                Event.error(
                    TargetUtils.getLocationMaybe(parentTarget),
                    TargetUtils.formatMissingEdge(parentTarget, toLabel, e, kind.getAttribute())));
      }
    }
    return false;
  }

  /**
   * Emits errors from {@link ExecutionPlatformResult#error}.
   *
   * <p>Exists to fetch the {@link BuildConfigurationValue}, needed to construct {@link
   * AnalysisRootCauseEvent}.
   */
  private class ExecGroupErrorEmitter implements StateMachine, Consumer<SkyValue> {
    // -------------------- Input --------------------
    private final String message;

    // -------------------- Internal State --------------------
    private BuildConfigurationValue configuration;

    private ExecGroupErrorEmitter(String message) {
      this.message = message;
    }

    @Override
    public StateMachine step(Tasks tasks) {
      // The configuration value should already exist as a dependency so this lookup is safe enough
      // for error handling.
      tasks.lookUp(parameters.configurationKey(), (Consumer<SkyValue>) this);
      return this::postEvent;
    }

    @Override
    public void accept(SkyValue value) {
      this.configuration = (BuildConfigurationValue) value;
    }

    private StateMachine postEvent(Tasks tasks) {
      parameters
          .eventHandler()
          .post(AnalysisRootCauseEvent.withConfigurationValue(configuration, toLabel, message));
      sink.acceptDependencyError(
          DependencyError.of(
              new DependencyEvaluationException(
                  new ConfiguredValueCreationException(
                      parameters.location(),
                      message,
                      parameters.label(),
                      parameters.eventId(),
                      /* rootCauses= */ null,
                      /* detailedExitCode= */ null),
                  // This error originates in dependency resolution, attached to the current target,
                  // so no dependency has reported the error.
                  /* depReportedOwnError= */ false)));
      return DONE;
    }
  }
}
