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

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.devtools.build.lib.skyframe.BzlLoadValue.keyForBuild;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.common.flogger.GoogleLogger;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.ActionGraph;
import com.google.devtools.build.lib.actions.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.actions.ActionLookupValue;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactFactory;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.actions.PackageRoots;
import com.google.devtools.build.lib.actions.ResourceManager;
import com.google.devtools.build.lib.actions.TestExecException;
import com.google.devtools.build.lib.actions.TotalAndConfiguredTargetOnlyMetric;
import com.google.devtools.build.lib.analysis.config.AdditionalConfigurationChangeEvent;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigRequestedEvent;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.constraints.PlatformRestrictionsResult;
import com.google.devtools.build.lib.analysis.constraints.RuleContextConstraintSemantics;
import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics;
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.bugreport.BugReporter;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.QuiescingExecutors;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.packages.AspectClass;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.NativeAspectClass;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.pkgcache.PackageManager.PackageManagerStatistics;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.SilentCloseable;
import com.google.devtools.build.lib.server.FailureDetails.Analysis;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.server.FailureDetails.Skyfocus;
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns.Code;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.TopLevelAspectsKey;
import com.google.devtools.build.lib.skyframe.BuildResultListener;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.CoverageReportValue;
import com.google.devtools.build.lib.skyframe.RepositoryMappingValue.RepositoryMappingResolutionException;
import com.google.devtools.build.lib.skyframe.SkyfocusState;
import com.google.devtools.build.lib.skyframe.SkyframeAnalysisAndExecutionResult;
import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult;
import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
import com.google.devtools.build.lib.skyframe.SkyframeBuildView.BuildDriverKeyTestContext;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.RegexFilter;
import com.google.devtools.build.skyframe.WalkableGraph;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

/**
 * The BuildView presents a semantically-consistent and transitively-closed dependency graph for
 * some set of packages.
 *
 * <h2>Package design</h2>
 *
 * <p>This package contains the Blaze dependency analysis framework (aka "analysis phase"). The goal
 * of this code is to perform semantic analysis of all of the build targets required for a given
 * build, to report errors/warnings for any problems in the input, and to construct an "action
 * graph" (see {@code lib.actions} package) correctly representing the work to be done during the
 * execution phase of the build.
 *
 * <p><b>Configurations</b> the inputs to a build come from two sources: the intrinsic inputs,
 * specified in the BUILD file, are called <em>targets</em>. The environmental inputs, coming from
 * the build tool, the command-line, or configuration files, are called the <em>configuration</em>.
 * Only when a target and a configuration are combined is there sufficient information to perform a
 * build.
 *
 * <p>Targets are implemented by the {@link Target} hierarchy in the {@code lib.packages} code.
 * Configurations are implemented by {@link BuildConfigurationValue}. The pair of these together is
 * represented by an instance of class {@link ConfiguredTarget}; this is the root of a hierarchy
 * with different implementations for each kind of target: source file, derived file, rules, etc.
 *
 * <p>The framework code in this package (as opposed to its subpackages) is responsible for
 * constructing the {@code ConfiguredTarget} graph for a given target and configuration, taking care
 * of such issues as:
 *
 * <ul>
 *   <li>caching common subgraphs.
 *   <li>detecting and reporting cycles.
 *   <li>correct propagation of errors through the graph.
 *   <li>reporting universal errors, such as dependencies from production code to tests, or to
 *       experimental branches.
 *   <li>capturing and replaying errors.
 *   <li>maintaining the graph from one build to the next to avoid unnecessary recomputation.
 *   <li>checking software licenses.
 * </ul>
 *
 * <p>See also {@link ConfiguredTarget} which documents some important invariants.
 *
 * <p>Lifespan: 1 invocation.
 */
public class BuildView {
  private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();

  private final BlazeDirectories directories;

  private final SkyframeExecutor skyframeExecutor;
  private final SkyframeBuildView skyframeBuildView;

  private final ConfiguredRuleClassProvider ruleClassProvider;

  @Nullable private ImmutableSet<Artifact> memoizedCoverageArtifacts;

  /** A factory class to create the coverage report action. May be null. */
  @Nullable private final CoverageReportActionFactory coverageReportActionFactory;

  public BuildView(
      BlazeDirectories directories,
      ConfiguredRuleClassProvider ruleClassProvider,
      SkyframeExecutor skyframeExecutor,
      CoverageReportActionFactory coverageReportActionFactory) {
    this.directories = directories;
    this.coverageReportActionFactory = coverageReportActionFactory;
    this.ruleClassProvider = ruleClassProvider;
    this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
    this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
  }

  /** Returns the number of analyzed targets/aspects. */
  public TotalAndConfiguredTargetOnlyMetric getEvaluatedCounts() {
    return skyframeBuildView.getEvaluatedCounts();
  }

  public TotalAndConfiguredTargetOnlyMetric getEvaluatedActionsCounts() {
    return skyframeBuildView.getEvaluatedActionCounts();
  }

  public PackageManagerStatistics getAndClearPkgManagerStatistics() {
    return skyframeExecutor.getPackageManager().getAndClearStatistics();
  }

  private ArtifactFactory getArtifactFactory() {
    return skyframeBuildView.getArtifactFactory();
  }

  /** Returns the collection of configured targets corresponding to any of the provided targets. */
  @VisibleForTesting
  static LinkedHashSet<ConfiguredTarget> filterTestsByTargets(
      Collection<ConfiguredTarget> targets, Set<Label> allowedTargetLabels) {
    return targets.stream()
        .filter(ct -> allowedTargetLabels.contains(ct.getLabel()))
        .collect(Collectors.toCollection(LinkedHashSet::new));
  }

  @ThreadCompatible
  public AnalysisResult update(
      TargetPatternPhaseValue loadingResult,
      BuildOptions targetOptions,
      ImmutableSet<Label> explicitTargetPatterns,
      List<String> aspects,
      ImmutableMap<String, String> aspectsParameters,
      AnalysisOptions viewOptions,
      boolean keepGoing,
      boolean skipIncompatibleExplicitTargets,
      boolean checkForActionConflicts,
      QuiescingExecutors executors,
      TopLevelArtifactContext topLevelOptions,
      boolean reportIncompatibleTargets,
      ExtendedEventHandler eventHandler,
      EventBus eventBus,
      BugReporter bugReporter,
      boolean includeExecutionPhase,
      int skymeldAnalysisOverlapPercentage,
      @Nullable ResourceManager resourceManager,
      @Nullable BuildResultListener buildResultListener,
      @Nullable ExecutionSetup executionSetupCallback,
      @Nullable BuildConfigurationsCreated buildConfigurationsCreatedCallback,
      @Nullable BuildDriverKeyTestContext buildDriverKeyTestContext,
      Optional<AdditionalConfigurationChangeEvent> additionalConfigurationChangeEvent)
      throws ViewCreationFailedException,
          InvalidConfigurationException,
          InterruptedException,
          BuildFailedException,
          TestExecException,
          AbruptExitException {
    logger.atInfo().log("Starting analysis");
    pollInterruptedStatus();

    skyframeBuildView.resetProgressReceiver();
    skyframeExecutor.setBaselineConfiguration(targetOptions);

    ImmutableMap.Builder<Label, Target> labelToTargetsMapBuilder =
        ImmutableMap.builderWithExpectedSize(loadingResult.getTargetLabels().size());
    loadingResult
        .getTargets(eventHandler, skyframeExecutor.getPackageManager())
        .forEach(target -> labelToTargetsMapBuilder.put(target.getLabel(), target));
    ImmutableMap<Label, Target> labelToTargetMap = labelToTargetsMapBuilder.buildOrThrow();

    eventBus.post(new AnalysisPhaseStartedEvent(labelToTargetMap.values()));

    // Prepare the analysis phase
    BuildConfigurationValue topLevelConfig;
    // Configuration creation.
    // TODO(gregce): Consider dropping this phase and passing on-the-fly target / exec configs as
    // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
    try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
      topLevelConfig = skyframeExecutor.createConfiguration(eventHandler, targetOptions, keepGoing);
      SkyfocusState skyfocusState = skyframeExecutor.getSkyfocusState();
      if (skyfocusState.enabled()) {
        boolean buildConfigChanged =
            skyfocusState.buildConfiguration() != null
                && !skyfocusState.buildConfiguration().equals(topLevelConfig);
        if (buildConfigChanged) {
          switch (skyfocusState.options().handlingStrategy) {
            case WARN -> {
              eventHandler.handle(
                  Event.warn(
                      "Skyfocus: detected changes to the build configuration, will be discarding"
                          + " the analysis cache."));
            }
            case STRICT ->
                throw new AbruptExitException(
                    DetailedExitCode.of(
                        FailureDetail.newBuilder()
                            .setMessage(
                                "Skyfocus: detected changes to the build configuration. This is not"
                                    + " allowed in a focused build. Either clean to reset the"
                                    + " build, or set"
                                    + " --experimental_skyfocus_handling_strategy=warn to perform a"
                                    + " full reanalysis instead of failing the build.")
                            .setSkyfocus(
                                Skyfocus.newBuilder()
                                    .setCode(Skyfocus.Code.CONFIGURATION_CHANGE)
                                    .build())
                            .build()));
          }
        }

        skyframeExecutor.setSkyfocusState(
            skyfocusState
                .withBuildConfiguration(topLevelConfig)
                .withForcedRerun(buildConfigChanged));
      }
      eventBus.post(new ConfigRequestedEvent(topLevelConfig, /* parentChecksum= */ null));
    }
    if (buildConfigurationsCreatedCallback != null) {
      buildConfigurationsCreatedCallback.run(topLevelConfig);
    }

    skyframeBuildView.setConfiguration(
        eventHandler,
        topLevelConfig,
        viewOptions.maxConfigChangesToShow,
        viewOptions.allowAnalysisCacheDiscards,
        additionalConfigurationChangeEvent);

    eventBus.post(new MakeEnvironmentEvent(topLevelConfig.getMakeEnvironment()));
    eventBus.post(topLevelConfig.toBuildEvent());

    var configurationKey = topLevelConfig.getKey();
    ImmutableList<ConfiguredTargetKey> topLevelCtKeys =
        labelToTargetMap.keySet().stream()
            .map(
                label ->
                    ConfiguredTargetKey.builder()
                        .setLabel(label)
                        .setConfigurationKey(configurationKey)
                        .build())
            .collect(toImmutableList());

    ImmutableList<TopLevelAspectsKey> aspectKeys =
        createTopLevelAspectKeys(
            aspects, aspectsParameters, labelToTargetMap.keySet(), topLevelConfig, eventHandler);

    getArtifactFactory().noteAnalysisStarting();
    SkyframeAnalysisResult skyframeAnalysisResult;
    try {
      if (includeExecutionPhase) {
        skyframeExecutor.setExtraActionFilter(viewOptions.extraActionFilter);
        skyframeExecutor.setRuleContextConstraintSemantics(
            (RuleContextConstraintSemantics) ruleClassProvider.getConstraintSemantics());
        // We wait until now to setup for execution, in case the artifact factory was reset
        // due to a config change.
        try (SilentCloseable c = Profiler.instance().profile("prepareForExecution")) {
          Preconditions.checkNotNull(executionSetupCallback).prepareForExecution();
        }
        skyframeAnalysisResult =
            skyframeBuildView.analyzeAndExecuteTargets(
                eventHandler,
                topLevelCtKeys,
                aspectKeys,
                loadingResult.getTestsToRunLabels(),
                labelToTargetMap,
                topLevelOptions,
                explicitTargetPatterns,
                eventBus,
                bugReporter,
                Preconditions.checkNotNull(resourceManager), // non-null for skymeld.
                Preconditions.checkNotNull(buildResultListener), // non-null for skymeld.
                (configuredTargets, allTargetsToTest) ->
                    memoizedGetCoverageArtifactsHelper(
                        configuredTargets, allTargetsToTest, eventHandler, eventBus, loadingResult),
                keepGoing,
                skipIncompatibleExplicitTargets,
                checkForActionConflicts,
                viewOptions.extraActionTopLevelOnly,
                executors,
                /* shouldDiscardAnalysisCache= */ viewOptions.discardAnalysisCache
                    || !skyframeExecutor.tracksStateForIncrementality(),
                buildDriverKeyTestContext,
                skymeldAnalysisOverlapPercentage);
      } else {
        skyframeAnalysisResult =
            skyframeBuildView.configureTargets(
                eventHandler,
                labelToTargetMap,
                topLevelCtKeys,
                aspectKeys,
                topLevelOptions,
                eventBus,
                bugReporter,
                keepGoing,
                executors,
                checkForActionConflicts);
        setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
      }
    } finally {
      skyframeBuildView.clearInvalidatedActionLookupKeys();
    }

    int numTargetsToAnalyze = labelToTargetMap.size();
    int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
    if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
      String msg =
          String.format(
              "%s succeeded for only %d of %d top-level targets",
              includeExecutionPhase ? "Build" : "Analysis", numSuccessful, numTargetsToAnalyze);
      eventHandler.handle(Event.info(msg));
      logger.atInfo().log("%s", msg);
    }

    AnalysisResult result;
    if (includeExecutionPhase) {
      // TODO(b/199053098): Also consider targets with errors like below.
      result =
          createResult(
              eventHandler,
              eventBus,
              loadingResult,
              topLevelConfig,
              topLevelOptions,
              viewOptions,
              skyframeAnalysisResult,
              /* targetsToSkip= */ ImmutableSet.of(),
              labelToTargetMap,
              /* includeExecutionPhase= */ true);
    } else {
      ImmutableSet<ConfiguredTarget> targetsToSkip = ImmutableSet.of();
      if (reportIncompatibleTargets) {
        TopLevelConstraintSemantics topLevelConstraintSemantics =
            new TopLevelConstraintSemantics(
                (RuleContextConstraintSemantics) ruleClassProvider.getConstraintSemantics(),
                skyframeExecutor.getPackageManager(),
                input -> skyframeExecutor.getConfiguration(eventHandler, input),
                eventHandler);

        PlatformRestrictionsResult platformRestrictions =
            topLevelConstraintSemantics.checkPlatformRestrictions(
                skyframeAnalysisResult.getConfiguredTargets(),
                explicitTargetPatterns,
                keepGoing,
                skipIncompatibleExplicitTargets);

        if (!platformRestrictions.targetsWithErrors().isEmpty()) {
          // If there are any errored targets (e.g. incompatible targets that are explicitly
          // specified on the command line), remove them from the list of targets to be built.
          skyframeAnalysisResult =
              skyframeAnalysisResult.withAdditionalErroredTargets(
                  platformRestrictions.targetsWithErrors());
        }

        targetsToSkip =
            Sets.union(
                    topLevelConstraintSemantics.checkTargetEnvironmentRestrictions(
                        skyframeAnalysisResult.getConfiguredTargets()),
                    platformRestrictions.targetsToSkip())
                .immutableCopy();
      }

      result =
          createResult(
              eventHandler,
              eventBus,
              loadingResult,
              topLevelConfig,
              topLevelOptions,
              viewOptions,
              skyframeAnalysisResult,
              targetsToSkip,
              labelToTargetMap,
              /* includeExecutionPhase= */ false);
    }
    logger.atInfo().log("Finished analysis");
    return result;
  }

  private ImmutableList<TopLevelAspectsKey> createTopLevelAspectKeys(
      List<String> aspects,
      ImmutableMap<String, String> aspectsParameters,
      ImmutableSet<Label> topLevelTargets,
      BuildConfigurationValue configuration,
      ExtendedEventHandler eventHandler)
      throws InterruptedException, ViewCreationFailedException {
    RepositoryMapping mainRepoMapping;
    try {
      mainRepoMapping = skyframeExecutor.getMainRepoMapping(eventHandler);
    } catch (RepositoryMappingResolutionException e) {
      String errorMessage =
          String.format(
              "Failed to get main repo mapping for aspect label canonicalization: %s",
              e.getMessage());
      throw new ViewCreationFailedException(
          errorMessage,
          createAnalysisFailureDetail(errorMessage, Analysis.Code.UNEXPECTED_ANALYSIS_EXCEPTION),
          e);
    }

    ImmutableList.Builder<AspectClass> aspectClassesBuilder = ImmutableList.builder();
    for (String aspect : aspects) {
      // Syntax: label%aspect
      int delimiterPosition = aspect.indexOf('%');
      if (delimiterPosition >= 0) {
        // TODO(jfield): For consistency with Starlark loads, the aspect should be specified
        // as an absolute label.
        // We convert it for compatibility reasons (this will be removed in the future).
        String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
        if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
          // "Legacy" behavior of '--aspects' parameter.
          if (bzlFileLoadLikeString.startsWith("/")) {
            bzlFileLoadLikeString = bzlFileLoadLikeString.substring(1);
          }
          int lastSlashPosition = bzlFileLoadLikeString.lastIndexOf('/');
          if (lastSlashPosition >= 0) {
            bzlFileLoadLikeString =
                "//"
                    + bzlFileLoadLikeString.substring(0, lastSlashPosition)
                    + ":"
                    + bzlFileLoadLikeString.substring(lastSlashPosition + 1);
          } else {
            bzlFileLoadLikeString = "//:" + bzlFileLoadLikeString;
          }
          if (!bzlFileLoadLikeString.endsWith(".bzl")) {
            bzlFileLoadLikeString = bzlFileLoadLikeString + ".bzl";
          }
        }
        Label starlarkFileLabel;
        try {
          starlarkFileLabel =
              Label.parseWithRepoContext(
                  bzlFileLoadLikeString,
                  Label.RepoContext.of(RepositoryName.MAIN, mainRepoMapping));
        } catch (LabelSyntaxException e) {
          String errorMessage = String.format("Invalid aspect '%s': %s", aspect, e.getMessage());
          throw new ViewCreationFailedException(
              errorMessage,
              createAnalysisFailureDetail(errorMessage, Analysis.Code.ASPECT_LABEL_SYNTAX_ERROR),
              e);
        }
        String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
        aspectClassesBuilder.add(
            new StarlarkAspectClass(keyForBuild(starlarkFileLabel), starlarkFunctionName));
      } else {
        final NativeAspectClass aspectFactoryClass =
            ruleClassProvider.getNativeAspectClassMap().get(aspect);

        if (aspectFactoryClass != null) {
          aspectClassesBuilder.add(aspectFactoryClass);
        } else {
          String errorMessage = "Aspect '" + aspect + "' is unknown";
          throw new ViewCreationFailedException(
              errorMessage,
              createAnalysisFailureDetail(errorMessage, Analysis.Code.ASPECT_NOT_FOUND));
        }
      }
    }
    ImmutableList<AspectClass> aspectClasses = aspectClassesBuilder.build();
    if (aspectClasses.isEmpty()) {
      return ImmutableList.of();
    }

    return topLevelTargets.stream()
        .map(
            target ->
                AspectKeyCreator.createTopLevelAspectsKey(
                    aspectClasses, target, configuration, aspectsParameters))
        .collect(toImmutableList());
  }

  private AnalysisResult createResult(
      ExtendedEventHandler eventHandler,
      EventBus eventBus,
      TargetPatternPhaseValue loadingResult,
      BuildConfigurationValue configuration,
      TopLevelArtifactContext topLevelOptions,
      AnalysisOptions viewOptions,
      SkyframeAnalysisResult skyframeAnalysisResult,
      Set<ConfiguredTarget> targetsToSkip,
      ImmutableMap<Label, Target> labelToTargetMap,
      boolean includeExecutionPhase)
      throws InterruptedException {
    ImmutableSet<Label> testsToRun = loadingResult.getTestsToRunLabels();
    Set<ConfiguredTarget> configuredTargets =
        Sets.newLinkedHashSet(skyframeAnalysisResult.getConfiguredTargets());
    ImmutableMap<AspectKey, ConfiguredAspect> aspects = skyframeAnalysisResult.getAspects();

    Set<ConfiguredTarget> allTargetsToTest = null;
    if (testsToRun != null) {
      // Determine the subset of configured targets that are meant to be run as tests.
      allTargetsToTest = filterTestsByTargets(configuredTargets, testsToRun);
    }

    ImmutableSet.Builder<Artifact> artifactsToBuild = ImmutableSet.builder();

    // build-info and build-changelist.
    ImmutableList<Artifact> buildInfoArtifacts =
        skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
    Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);

    // Extra actions
    addExtraActionsIfRequested(
        viewOptions, configuredTargets, aspects, artifactsToBuild, eventHandler);

    // Coverage
    artifactsToBuild.addAll(
        memoizedGetCoverageArtifactsHelper(
            configuredTargets, allTargetsToTest, eventHandler, eventBus, loadingResult));

    // TODO(cparsons): If extra actions are ever removed, this filtering step can probably be
    //  removed as well: the only concern would be action conflicts involving coverage artifacts,
    //  which seems far-fetched.
    if (skyframeAnalysisResult.hasActionConflicts()) {
      // We don't remove the (hopefully unnecessary) guard in SkyframeBuildView that enables/
      // disables analysis, since no new targets should actually be analyzed.
      ImmutableSet<Artifact> artifacts = artifactsToBuild.build();
      Predicate<Artifact> errorFreeArtifacts =
          skyframeExecutor.filterActionConflictsForTopLevelArtifacts(eventHandler, artifacts);

      artifactsToBuild = ImmutableSet.builder();
      artifacts.stream().filter(errorFreeArtifacts).forEach(artifactsToBuild::add);
    }
    // Build-info artifacts are always conflict-free, and can't be checked easily.
    buildInfoArtifacts.forEach(artifactsToBuild::add);

    // Tests.
    ImmutableSet.Builder<ConfiguredTarget> parallelTestsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<ConfiguredTarget> exclusiveTestsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<ConfiguredTarget> exclusiveIfLocalTestsBuilder = ImmutableSet.builder();
    collectTests(
        topLevelOptions,
        allTargetsToTest,
        labelToTargetMap,
        parallelTestsBuilder,
        exclusiveTestsBuilder,
        exclusiveIfLocalTestsBuilder);
    ImmutableSet<ConfiguredTarget> parallelTests = parallelTestsBuilder.build();
    ImmutableSet<ConfiguredTarget> exclusiveTests = exclusiveTestsBuilder.build();
    ImmutableSet<ConfiguredTarget> exclusiveIfLocalTests = exclusiveIfLocalTestsBuilder.build();

    FailureDetail failureDetail =
        createAnalysisFailureDetail(loadingResult, skyframeAnalysisResult);
    if (includeExecutionPhase) {
      SkyframeAnalysisAndExecutionResult skyframeAnalysisAndExecutionResult =
          (SkyframeAnalysisAndExecutionResult) skyframeAnalysisResult;
      return new AnalysisAndExecutionResult(
          configuration,
          ImmutableSet.copyOf(configuredTargets),
          aspects,
          allTargetsToTest == null ? null : ImmutableSet.copyOf(allTargetsToTest),
          ImmutableSet.copyOf(targetsToSkip),
          failureDetail,
          skyframeAnalysisAndExecutionResult.getRepresentativeExecutionExitCode(),
          artifactsToBuild.build(),
          parallelTests,
          exclusiveTests,
          exclusiveIfLocalTests,
          topLevelOptions,
          loadingResult.getWorkspaceName(),
          skyframeAnalysisResult.getTargetsWithConfiguration());
    }

    WalkableGraph graph = skyframeAnalysisResult.getWalkableGraph();
    ActionGraph actionGraph =
        new ActionGraph() {
          @Nullable
          @Override
          public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
            if (artifact.isSourceArtifact()) {
              return null;
            }
            ActionLookupData generatingActionKey =
                ((Artifact.DerivedArtifact) artifact).getGeneratingActionKey();
            ActionLookupValue val;
            try {
              val = (ActionLookupValue) graph.getValue(generatingActionKey.getActionLookupKey());
            } catch (InterruptedException e) {
              throw new IllegalStateException(
                  "Interruption not expected from this graph: " + generatingActionKey, e);
            }
            if (val == null) {
              logger.atWarning().atMostEvery(1, TimeUnit.SECONDS).log(
                  "Missing generating action for %s (%s)", artifact, generatingActionKey);
              return null;
            }
            return val.getActions().get(generatingActionKey.getActionIndex());
          }
        };
    return new AnalysisResult(
        configuration,
        ImmutableSet.copyOf(configuredTargets),
        aspects,
        allTargetsToTest == null ? null : ImmutableSet.copyOf(allTargetsToTest),
        ImmutableSet.copyOf(targetsToSkip),
        failureDetail,
        actionGraph,
        artifactsToBuild.build(),
        parallelTests,
        exclusiveTests,
        exclusiveIfLocalTests,
        topLevelOptions,
        skyframeAnalysisResult.getPackageRoots(),
        loadingResult.getWorkspaceName(),
        skyframeAnalysisResult.getTargetsWithConfiguration());
  }

  /**
   * Check for errors in "chronological" order (acknowledge that loading and analysis are
   * interleaved, but sequential on the single target scale).
   */
  @Nullable
  public static FailureDetail createAnalysisFailureDetail(
      TargetPatternPhaseValue loadingResult,
      @Nullable SkyframeAnalysisResult skyframeAnalysisResult) {
    if (loadingResult.hasError()) {
      return FailureDetail.newBuilder()
          .setMessage("command succeeded, but there were errors parsing the target pattern")
          .setTargetPatterns(TargetPatterns.newBuilder().setCode(Code.TARGET_PATTERN_PARSE_FAILURE))
          .build();
    }
    if (loadingResult.hasPostExpansionError()
        || (skyframeAnalysisResult != null && skyframeAnalysisResult.hasLoadingError())) {
      return FailureDetail.newBuilder()
          .setMessage("command succeeded, but there were loading phase errors")
          .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.GENERIC_LOADING_PHASE_FAILURE))
          .build();
    }
    if (skyframeAnalysisResult != null && skyframeAnalysisResult.hasAnalysisError()) {
      return FailureDetail.newBuilder()
          .setMessage("command succeeded, but not all targets were analyzed")
          .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.NOT_ALL_TARGETS_ANALYZED))
          .build();
    }
    return null;
  }

  private static FailureDetail createAnalysisFailureDetail(
      String errorMessage, Analysis.Code code) {
    return FailureDetail.newBuilder()
        .setMessage(errorMessage)
        .setAnalysis(Analysis.newBuilder().setCode(code))
        .build();
  }

  private static NestedSet<Artifact> getBaselineCoverageArtifacts(
      Collection<ConfiguredTarget> configuredTargets) {
    NestedSetBuilder<Artifact> baselineCoverageArtifacts = NestedSetBuilder.stableOrder();
    for (ConfiguredTarget target : configuredTargets) {
      InstrumentedFilesInfo provider = target.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
      if (provider != null) {
        baselineCoverageArtifacts.addTransitive(provider.getBaselineCoverageArtifacts());
      }
    }
    return baselineCoverageArtifacts.build();
  }

  private void addExtraActionsIfRequested(
      AnalysisOptions viewOptions,
      Collection<ConfiguredTarget> configuredTargets,
      ImmutableMap<AspectKey, ConfiguredAspect> aspects,
      ImmutableSet.Builder<Artifact> artifactsToBuild,
      ExtendedEventHandler eventHandler) {
    RegexFilter filter = viewOptions.extraActionFilter;
    for (ConfiguredTarget target : configuredTargets) {
      ExtraActionArtifactsProvider provider =
          target.getProvider(ExtraActionArtifactsProvider.class);
      if (provider != null) {
        if (viewOptions.extraActionTopLevelOnly) {
          // Collect all aspect-classes that topLevel might inject.
          Set<AspectClass> aspectClasses = new HashSet<>();
          Target actualTarget = null;
          try {
            actualTarget =
                skyframeExecutor.getPackageManager().getTarget(eventHandler, target.getLabel());
          } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
            eventHandler.handle(Event.error(""));
          }
          for (Attribute attr : actualTarget.getAssociatedRule().getAttributes()) {
            aspectClasses.addAll(attr.getAspectClasses());
          }
          addArtifactsToBuilder(
              provider.getExtraActionArtifacts().toList(), artifactsToBuild, filter);
          if (!aspectClasses.isEmpty()) {
            addArtifactsToBuilder(
                filterTransitiveExtraActions(provider, aspectClasses), artifactsToBuild, filter);
          }
        } else {
          addArtifactsToBuilder(
              provider.getTransitiveExtraActionArtifacts().toList(), artifactsToBuild, filter);
        }
      }
    }
    for (Map.Entry<AspectKey, ConfiguredAspect> aspectEntry : aspects.entrySet()) {
      ExtraActionArtifactsProvider provider =
          aspectEntry.getValue().getProvider(ExtraActionArtifactsProvider.class);
      if (provider != null) {
        if (viewOptions.extraActionTopLevelOnly) {
          addArtifactsToBuilder(
              provider.getExtraActionArtifacts().toList(), artifactsToBuild, filter);
        } else {
          addArtifactsToBuilder(
              provider.getTransitiveExtraActionArtifacts().toList(), artifactsToBuild, filter);
        }
      }
    }
  }

  private static void addArtifactsToBuilder(
      List<? extends Artifact> artifacts,
      ImmutableSet.Builder<Artifact> builder,
      RegexFilter filter) {
    for (Artifact artifact : artifacts) {
      if (filter.isIncluded(artifact.getOwnerLabel().toString())) {
        builder.add(artifact);
      }
    }
  }

  /**
   * Returns a list of artifacts from 'provider' that were registered by an aspect from
   * 'aspectClasses'. All artifacts in 'provider' are considered - both direct and transitive.
   */
  private static ImmutableList<Artifact> filterTransitiveExtraActions(
      ExtraActionArtifactsProvider provider, Set<AspectClass> aspectClasses) {
    ImmutableList.Builder<Artifact> artifacts = ImmutableList.builder();
    // Add to 'artifacts' all extra-actions which were registered by aspects which 'topLevel'
    // might have injected.
    for (Artifact.DerivedArtifact artifact :
        provider.getTransitiveExtraActionArtifacts().toList()) {
      ActionLookupKey owner = artifact.getArtifactOwner();
      if (owner instanceof AspectKey aspectKey) {
        if (aspectClasses.contains(aspectKey.getAspectClass())) {
          artifacts.add(artifact);
        }
      }
    }
    return artifacts.build();
  }

  private static void collectTests(
      TopLevelArtifactContext topLevelOptions,
      @Nullable Iterable<ConfiguredTarget> allTestTargets,
      ImmutableMap<Label, Target> labelToTargetMap,
      ImmutableSet.Builder<ConfiguredTarget> parallelTests,
      ImmutableSet.Builder<ConfiguredTarget> exclusiveTests,
      ImmutableSet.Builder<ConfiguredTarget> exclusiveIfLocalTests) {
    Set<String> outputGroups = topLevelOptions.outputGroups();
    if (!outputGroups.contains(OutputGroupInfo.FILES_TO_COMPILE)
        && !outputGroups.contains(OutputGroupInfo.COMPILATION_PREREQUISITES)
        && allTestTargets != null) {
      final boolean isExclusive = topLevelOptions.runTestsExclusively();
      for (ConfiguredTarget configuredTarget : allTestTargets) {
        Target target = labelToTargetMap.get(configuredTarget.getLabel());
        if (target instanceof Rule rule) {
          if (isExclusive || TargetUtils.isExclusiveTestRule(rule)) {
            exclusiveTests.add(configuredTarget);
          } else if (TargetUtils.isExclusiveIfLocalTestRule((Rule) target)
              && TargetUtils.isLocalTestRule((Rule) target)) {
            exclusiveTests.add(configuredTarget);
          } else if (TargetUtils.isExclusiveIfLocalTestRule((Rule) target)) {
            exclusiveIfLocalTests.add(configuredTarget);
          } else {
            parallelTests.add(configuredTarget);
          }
        }
      }
    }
  }

  /**
   * Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
   * paths with unknown roots to artifacts.
   */
  private void setArtifactRoots(PackageRoots packageRoots) {
    getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
  }

  /** Performs the necessary setups for the execution phase. */
  @FunctionalInterface
  public interface ExecutionSetup {
    void prepareForExecution()
        throws AbruptExitException, BuildFailedException, InvalidConfigurationException,
            InterruptedException;
  }

  /** The callback for when BuildConfigurationValue is available. */
  @FunctionalInterface
  public interface BuildConfigurationsCreated {
    void run(BuildConfigurationValue buildConfiguration);
  }

  /**
   * Tests and clears the current thread's pending "interrupted" status, and throws
   * InterruptedException iff it was set.
   */
  private static void pollInterruptedStatus() throws InterruptedException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
  }

  private ImmutableSet<Artifact> memoizedGetCoverageArtifactsHelper(
      Set<ConfiguredTarget> configuredTargets,
      Set<ConfiguredTarget> allTargetsToTest,
      EventHandler eventHandler,
      EventBus eventBus,
      TargetPatternPhaseValue loadingResult)
      throws InterruptedException {
    if (memoizedCoverageArtifacts == null) {
      memoizedCoverageArtifacts =
          constructCoverageArtifacts(
              configuredTargets, allTargetsToTest, eventHandler, eventBus, loadingResult);
    }
    return memoizedCoverageArtifacts;
  }

  private ImmutableSet<Artifact> constructCoverageArtifacts(
      Set<ConfiguredTarget> configuredTargets,
      Set<ConfiguredTarget> allTargetsToTest,
      EventHandler eventHandler,
      EventBus eventBus,
      TargetPatternPhaseValue loadingResult)
      throws InterruptedException {
    if (coverageReportActionFactory == null) {
      return ImmutableSet.of();
    }
    CoverageReportActionsWrapper actionsWrapper =
        coverageReportActionFactory.createCoverageReportActionsWrapper(
            eventHandler,
            eventBus,
            directories,
            allTargetsToTest,
            getBaselineCoverageArtifacts(configuredTargets),
            getArtifactFactory(),
            skyframeExecutor.getActionKeyContext(),
            CoverageReportValue.COVERAGE_REPORT_KEY,
            loadingResult.getWorkspaceName());
    if (actionsWrapper == null) {
      return ImmutableSet.of();
    }
    skyframeExecutor.injectCoverageReportData(actionsWrapper.getActions());
    return ImmutableSet.copyOf(actionsWrapper.getCoverageOutputs());
  }
}
