// 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.lib.skyframe.config.PlatformMappingException;
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)));
  }

  @Override
  public void acceptPlatformMappingError(PlatformMappingException e) {
    sink.acceptDependencyError(DependencyError.of(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;
    }
  }
}
