// 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.rules.cpp;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionEnvironment;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.CcCommon.CoptsFilter;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;

/** Builder class to construct C++ compile actions. */
public final class CppCompileActionBuilder {

  private final ActionOwner owner;
  private boolean shareable;
  private final BuildConfigurationValue configuration;
  private CcToolchainFeatures.FeatureConfiguration featureConfiguration;
  private CcToolchainVariables variables = CcToolchainVariables.EMPTY;
  private Artifact sourceFile;
  private final NestedSetBuilder<Artifact> mandatoryInputsBuilder;
  private Artifact outputFile;
  private Artifact dwoFile;
  private Artifact ltoIndexingFile;
  private Artifact dotdFile;
  private Artifact diagnosticsFile;
  private Artifact gcnoFile;
  private CcCompilationContext ccCompilationContext = CcCompilationContext.EMPTY;
  private final List<String> pluginOpts = new ArrayList<>();
  private CoptsFilter coptsFilter = CoptsFilter.alwaysPasses();
  private ImmutableList<PathFragment> extraSystemIncludePrefixes = ImmutableList.of();
  private boolean usePic;
  private final CppConfiguration cppConfiguration;
  private final ArrayList<Artifact> additionalIncludeScanningRoots;
  private Boolean shouldScanIncludes;
  private Map<String, String> executionInfo = new LinkedHashMap<>();
  private final CppSemantics cppSemantics;
  private final CcToolchainProvider ccToolchain;
  @Nullable private String actionName;
  private ImmutableList<Artifact> buildInfoHeaderArtifacts = ImmutableList.of();
  private NestedSet<Artifact> cacheKeyInputs = NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  private NestedSet<Artifact> additionalPrunableHeaders =
      NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  private ImmutableList<Artifact> additionalOutputs = ImmutableList.of();
  // New fields need to be added to the copy constructor.

  /** Creates a builder from a rule and configuration. */
  public CppCompileActionBuilder(
      ActionConstructionContext actionConstructionContext,
      CcToolchainProvider ccToolchain,
      BuildConfigurationValue configuration,
      CppSemantics cppSemantics) {

    ActionOwner actionOwner = null;
    if (actionConstructionContext instanceof RuleContext
        && ((RuleContext) actionConstructionContext).useAutoExecGroups()) {
      actionOwner = actionConstructionContext.getActionOwner(cppSemantics.getCppToolchainType());
    }

    this.owner = actionOwner == null ? actionConstructionContext.getActionOwner() : actionOwner;
    this.shareable = false;
    this.configuration = configuration;
    this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
    this.mandatoryInputsBuilder = NestedSetBuilder.stableOrder();
    this.additionalIncludeScanningRoots = new ArrayList<>();
    this.ccToolchain = ccToolchain;
    this.cppSemantics = cppSemantics;
  }

  /**
   * Creates a builder that is a copy of another builder.
   */
  public CppCompileActionBuilder(CppCompileActionBuilder other) {
    this.owner = other.owner;
    this.shareable = other.shareable;
    this.featureConfiguration = other.featureConfiguration;
    this.sourceFile = other.sourceFile;
    this.mandatoryInputsBuilder = NestedSetBuilder.<Artifact>stableOrder()
        .addTransitive(other.mandatoryInputsBuilder.build());
    this.additionalIncludeScanningRoots = new ArrayList<>();
    this.additionalIncludeScanningRoots.addAll(other.additionalIncludeScanningRoots);
    this.outputFile = other.outputFile;
    this.dwoFile = other.dwoFile;
    this.ltoIndexingFile = other.ltoIndexingFile;
    this.dotdFile = other.dotdFile;
    this.gcnoFile = other.gcnoFile;
    this.ccCompilationContext = other.ccCompilationContext;
    this.pluginOpts.addAll(other.pluginOpts);
    this.coptsFilter = other.coptsFilter;
    this.extraSystemIncludePrefixes = other.extraSystemIncludePrefixes;
    this.cppConfiguration = other.cppConfiguration;
    this.configuration = other.configuration;
    this.usePic = other.usePic;
    this.shouldScanIncludes = other.shouldScanIncludes;
    this.executionInfo = new LinkedHashMap<>(other.executionInfo);
    this.cppSemantics = other.cppSemantics;
    this.ccToolchain = other.ccToolchain;
    this.actionName = other.actionName;
    this.additionalOutputs = other.additionalOutputs;
  }

  public CppCompileActionBuilder setSourceFile(Artifact sourceFile) {
    Preconditions.checkState(
        this.sourceFile == null,
        "New source file %s trying to overwrite old source file %s",
        sourceFile,
        this.sourceFile);
    return setSourceFileUnchecked(sourceFile);
  }

  public CppCompileActionBuilder setSourceFile(Artifact.TreeFileArtifact sourceFile) {
    Preconditions.checkState(
        !(this.sourceFile instanceof Artifact.TreeFileArtifact),
        "New source file %s trying to overwrite old source file %s also a tree file artifact",
        sourceFile,
        this.sourceFile);
    return setSourceFileUnchecked(sourceFile);
  }

  @CanIgnoreReturnValue
  private CppCompileActionBuilder setSourceFileUnchecked(Artifact sourceFile) {
    this.sourceFile = sourceFile;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setAdditionalOutputs(ImmutableList<Artifact> additionalOutputs) {
    this.additionalOutputs = additionalOutputs;
    return this;
  }

  public Artifact getSourceFile() {
    return sourceFile;
  }

  public CcCompilationContext getCcCompilationContext() {
    return ccCompilationContext;
  }

  public NestedSet<Artifact> getMandatoryInputs() {
    return mandatoryInputsBuilder.build();
  }

  public String getActionName() {
    if (actionName != null) {
      return actionName;
    }
    PathFragment sourcePath = sourceFile.getExecPath();
    if (CppFileTypes.CPP_MODULE_MAP.matches(sourcePath)) {
      return CppActionNames.CPP_MODULE_COMPILE;
    } else if (CppFileTypes.CPP_HEADER.matches(sourcePath)) {
      // TODO(bazel-team): Handle C headers that probably don't work in C++ mode.
      if (featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS)) {
        return CppActionNames.CPP_HEADER_PARSING;
      }
      // CcCommon.collectCAndCppSources() ensures we do not add headers to
      // the compilation artifacts unless 'parse_headers' is set.
      throw new IllegalStateException();
    } else if (CppFileTypes.C_SOURCE.matches(sourcePath)) {
      return CppActionNames.C_COMPILE;
    } else if (CppFileTypes.CPP_SOURCE.matches(sourcePath)) {
      return CppActionNames.CPP_COMPILE;
    } else if (CppFileTypes.OBJC_SOURCE.matches(sourcePath)) {
      return CppActionNames.OBJC_COMPILE;
    } else if (CppFileTypes.OBJCPP_SOURCE.matches(sourcePath)) {
      return CppActionNames.OBJCPP_COMPILE;
    } else if (CppFileTypes.ASSEMBLER.matches(sourcePath)) {
      return CppActionNames.ASSEMBLE;
    } else if (CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR.matches(sourcePath)) {
      return CppActionNames.PREPROCESS_ASSEMBLE;
    } else if (CppFileTypes.CLIF_INPUT_PROTO.matches(sourcePath)) {
      return CppActionNames.CLIF_MATCH;
    } else if (CppFileTypes.CPP_MODULE.matches(sourcePath)) {
      return CppActionNames.CPP_MODULE_CODEGEN;
    }
    // CcCompilationHelper ensures CppCompileAction only gets instantiated for supported file types.
    throw new IllegalStateException();
  }

  /**
   * Builds the Action as configured and performs some validations on the action. Uses {@link
   * RuleContext#throwWithRuleError(String)} to report errors. Prefer this method over {@link
   * CppCompileActionBuilder#buildOrThrowIllegalStateException()} whenever possible (meaning
   * whenever you have access to {@link RuleContext}).
   *
   * <p>This method may be called multiple times to create multiple compile actions (usually after
   * calling some setters to modify the generated action).
   */
  CppCompileAction buildOrThrowRuleError(RuleErrorConsumer ruleErrorConsumer)
      throws RuleErrorException {
    try {
      return buildAndVerify();
    } catch (UnconfiguredActionConfigException e) {
      throw ruleErrorConsumer.throwWithRuleError(e.getMessage());
    } catch (EvalException e) {
      throw ruleErrorConsumer.throwWithRuleError(e.getMessage());
    }
  }

  /**
   * Builds the Action as configured and performs some validations on the action. Throws {@link
   * IllegalStateException} to report errors. Prefer {@link
   * CppCompileActionBuilder#buildOrThrowRuleError(RuleErrorConsumer)} over this method whenever
   * possible (meaning whenever you have access to {@link RuleContext}).
   *
   * <p>This method may be called multiple times to create multiple compile actions (usually after
   * calling some setters to modify the generated action).
   */
  public CppCompileAction buildOrThrowIllegalStateException() {
    try {
      return buildAndVerify();
    } catch (UnconfiguredActionConfigException | EvalException e) {
      throw new IllegalStateException(e);
    }
  }

  static final class UnconfiguredActionConfigException extends Exception {
    private UnconfiguredActionConfigException(String actionName) {
      super(String.format("Expected action_config for '%s' to be configured", actionName));
    }
  }

  /**
   * Builds the Action as configured and performs some validations on the action. Uses given {@link
   * Consumer} to collect validation errors.
   */
  public CppCompileAction buildAndVerify() throws UnconfiguredActionConfigException, EvalException {
    // This must be set either to false or true by CppSemantics, otherwise someone forgot to call
    // finalizeCompileActionBuilder on this builder.
    Preconditions.checkNotNull(shouldScanIncludes);
    Preconditions.checkNotNull(featureConfiguration);
    boolean useHeaderModules = useHeaderModules();

    String actionName = getActionName();
    if (featureConfiguration.actionIsConfigured(actionName)) {
      for (String executionRequirement :
          featureConfiguration.getToolRequirementsForAction(actionName)) {
        executionInfo.put(executionRequirement, "");
      }
    } else {
      throw new UnconfiguredActionConfigException(actionName);
    }

    NestedSet<Artifact> realMandatorySpawnInputs = buildMandatoryInputs();
    NestedSet<Artifact> realMandatoryInputs =
        new NestedSetBuilder<Artifact>(Order.STABLE_ORDER)
            .addTransitive(realMandatorySpawnInputs)
            .addTransitive(cacheKeyInputs)
            .build();
    NestedSet<Artifact> prunableHeaders = additionalPrunableHeaders;

    configuration.modifyExecutionInfo(
        executionInfo,
        CppCompileAction.actionNameToMnemonic(
            actionName, featureConfiguration, cppConfiguration.useCppCompileHeaderMnemonic()));

    // Copying the collections is needed to make the builder reusable.
    return new CppCompileAction(
        owner,
        featureConfiguration,
        variables,
        sourceFile,
        configuration,
        shareable,
        shouldScanIncludes,
        usePic,
        useHeaderModules,
        realMandatoryInputs,
        realMandatorySpawnInputs,
        getBuiltinIncludeFiles(),
        prunableHeaders,
        outputFile,
        dotdFile,
        diagnosticsFile,
        gcnoFile,
        dwoFile,
        ltoIndexingFile,
        ccCompilationContext,
        coptsFilter,
        ImmutableList.copyOf(additionalIncludeScanningRoots),
        ImmutableMap.copyOf(executionInfo),
        actionName,
        cppSemantics,
        getBuiltinIncludeDirectories(),
        ccToolchain.getGrepIncludes(),
        additionalOutputs);
  }

  private ImmutableList<Artifact> getBuiltinIncludeFiles() throws EvalException {
    ImmutableList<Artifact> builtinIncludeFiles = ccToolchain.getBuiltinIncludeFiles();
    if (buildInfoHeaderArtifacts.isEmpty()) {
      return builtinIncludeFiles;
    }
    if (builtinIncludeFiles.isEmpty()) {
      return buildInfoHeaderArtifacts;
    }
    return ImmutableList.<Artifact>builderWithExpectedSize(
            builtinIncludeFiles.size() + buildInfoHeaderArtifacts.size())
        .addAll(builtinIncludeFiles)
        .addAll(buildInfoHeaderArtifacts)
        .build();
  }

  private boolean shouldParseShowIncludes() {
    return featureConfiguration.isEnabled(CppRuleClasses.PARSE_SHOWINCLUDES);
  }

  /** Returns the list of mandatory inputs for the {@link CppCompileAction} as configured. */
  NestedSet<Artifact> buildMandatoryInputs() throws EvalException {
    NestedSetBuilder<Artifact> realMandatoryInputsBuilder = NestedSetBuilder.compileOrder();
    realMandatoryInputsBuilder.addTransitive(mandatoryInputsBuilder.build());
    realMandatoryInputsBuilder.addAll(getBuiltinIncludeFiles());
    if (useHeaderModules() && !shouldScanIncludes) {
      realMandatoryInputsBuilder.addTransitive(ccCompilationContext.getTransitiveModules(usePic));
    }
    ccCompilationContext.addAdditionalInputs(realMandatoryInputsBuilder);
    realMandatoryInputsBuilder.add(Preconditions.checkNotNull(sourceFile));
    if (ccToolchain.getGrepIncludes() != null) {
      realMandatoryInputsBuilder.add(ccToolchain.getGrepIncludes());
    }
    if (!shouldScanIncludes && dotdFile == null && !shouldParseShowIncludes()) {
      realMandatoryInputsBuilder.addTransitive(ccCompilationContext.getDeclaredIncludeSrcs());
      realMandatoryInputsBuilder.addTransitive(additionalPrunableHeaders);
    }
    return realMandatoryInputsBuilder.build();
  }

  NestedSet<Artifact> getPrunableHeaders() {
    return additionalPrunableHeaders;
  }

  NestedSet<Artifact> getInputsForInvalidation() {
    return ccCompilationContext.getTransitiveCompilationPrerequisites();
  }

  private boolean useHeaderModules(Artifact sourceFile) {
    Preconditions.checkNotNull(featureConfiguration);
    Preconditions.checkNotNull(sourceFile);
    return featureConfiguration.isEnabled(CppRuleClasses.USE_HEADER_MODULES)
        && (sourceFile.isFileType(CppFileTypes.CPP_SOURCE)
            || sourceFile.isFileType(CppFileTypes.CPP_HEADER)
            || sourceFile.isFileType(CppFileTypes.CPP_MODULE_MAP));
  }

  private boolean useHeaderModules() {
    return useHeaderModules(sourceFile);
  }

  /**
   * Set action name that is used to pick the right action_config and features from {@link
   * FeatureConfiguration}. By default the action name is decided from the source filetype.
   */
  @CanIgnoreReturnValue
  public CppCompileActionBuilder setActionName(String actionName) {
    Preconditions.checkState(
        this.actionName == null,
        "New actionName %s trying to overwrite old name %s",
        actionName,
        this.actionName);
    this.actionName = actionName;
    return this;
  }

  /** Sets the feature configuration to be used for the action. */
  @CanIgnoreReturnValue
  public CppCompileActionBuilder setFeatureConfiguration(
      FeatureConfiguration featureConfiguration) {
    Preconditions.checkNotNull(featureConfiguration);
    this.featureConfiguration = featureConfiguration;
    return this;
  }

  FeatureConfiguration getFeatureConfiguration() {
    return featureConfiguration;
  }

  /** Sets the feature build variables to be used for the action. */
  @CanIgnoreReturnValue
  public CppCompileActionBuilder setVariables(CcToolchainVariables variables) {
    this.variables = variables;
    return this;
  }

  /** Returns the build variables to be used for the action. */
  public CcToolchainVariables getVariables() {
    return variables;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder addExecutionInfo(Map<String, String> executionInfo) {
    this.executionInfo.putAll(executionInfo);
    return this;
  }

  Map<String, String> getExecutionInfo() {
    return executionInfo;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder addMandatoryInputs(NestedSet<Artifact> artifacts) {
    mandatoryInputsBuilder.addTransitive(artifacts);
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder addMandatoryInputs(List<Artifact> artifacts) {
    mandatoryInputsBuilder.addAll(artifacts);
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder addTransitiveMandatoryInputs(NestedSet<Artifact> artifacts) {
    mandatoryInputsBuilder.addTransitive(artifacts);
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder addAdditionalIncludeScanningRoots(
      List<Artifact> additionalIncludeScanningRoots) {
    this.additionalIncludeScanningRoots.addAll(additionalIncludeScanningRoots);
    return this;
  }

  public boolean useDotdFile(Artifact sourceFile) {
    return CppFileTypes.headerDiscoveryRequired(sourceFile) && !useHeaderModules(sourceFile);
  }

  public boolean dotdFilesEnabled() {
    return cppSemantics.needsDotdInputPruning(configuration)
        && !shouldParseShowIncludes()
        && !featureConfiguration.isEnabled(CppRuleClasses.NO_DOTD_FILE);
  }

  public boolean serializedDiagnosticsFilesEnabled() {
    return featureConfiguration.isEnabled(CppRuleClasses.SERIALIZED_DIAGNOSTICS_FILE);
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setOutputs(
      Artifact outputFile, Artifact dotdFile, Artifact diagnosticsFile) {
    this.outputFile = outputFile;
    this.dotdFile = dotdFile;
    this.diagnosticsFile = diagnosticsFile;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setOutputs(
      ActionConstructionContext actionConstructionContext,
      RuleErrorConsumer ruleErrorConsumer,
      Label label,
      ArtifactCategory outputCategory,
      String outputName)
      throws RuleErrorException {
    this.outputFile =
        CppHelper.getCompileOutputArtifact(
            actionConstructionContext,
            label,
            CppHelper.getArtifactNameForCategory(ccToolchain, outputCategory, outputName),
            configuration);
    if (dotdFilesEnabled() && useDotdFile(sourceFile)) {
      String dotdFileName = CppHelper.getDotdFileName(ccToolchain, outputCategory, outputName);
      dotdFile =
          CppHelper.getCompileOutputArtifact(
              actionConstructionContext, label, dotdFileName, configuration);
    } else {
      dotdFile = null;
    }
    if (serializedDiagnosticsFilesEnabled()) {
      String diagnosticsFileName =
          CppHelper.getDiagnosticsFileName(ccToolchain, outputCategory, outputName);
      diagnosticsFile =
          CppHelper.getCompileOutputArtifact(
              actionConstructionContext, label, diagnosticsFileName, configuration);
    } else {
      diagnosticsFile = null;
    }
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setDwoFile(Artifact dwoFile) {
    this.dwoFile = dwoFile;
    return this;
  }

  /**
   * Set the minimized bitcode file emitted by this (ThinLTO) compilation that can be used in place
   * of the full bitcode outputFile in the LTO indexing step.
   */
  @CanIgnoreReturnValue
  public CppCompileActionBuilder setLtoIndexingFile(Artifact ltoIndexingFile) {
    this.ltoIndexingFile = ltoIndexingFile;
    return this;
  }

  public Artifact getOutputFile() {
    return outputFile;
  }

  public Artifact getDotdFile() {
    return this.dotdFile;
  }

  public Artifact getDiagnosticsFile() {
    return this.diagnosticsFile;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setGcnoFile(Artifact gcnoFile) {
    this.gcnoFile = gcnoFile;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setCcCompilationContext(
      CcCompilationContext ccCompilationContext) {
    this.ccCompilationContext = ccCompilationContext;
    return this;
  }

  /** Sets whether the CompileAction should use pic mode. */
  @CanIgnoreReturnValue
  public CppCompileActionBuilder setPicMode(boolean usePic) {
    this.usePic = usePic;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setShareable(boolean shareable) {
    this.shareable = shareable;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setShouldScanIncludes(boolean shouldScanIncludes) {
    this.shouldScanIncludes = shouldScanIncludes;
    return this;
  }

  public boolean getShouldScanIncludes() {
    return shouldScanIncludes;
  }

  public CcToolchainProvider getToolchain() {
    return ccToolchain;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setCoptsFilter(CoptsFilter coptsFilter) {
    this.coptsFilter = Preconditions.checkNotNull(coptsFilter);
    return this;
  }

  CoptsFilter getCoptsFilter() {
    return coptsFilter;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setBuildInfoHeaderArtifacts(
      ImmutableList<Artifact> buildInfoHeaderArtifacts) {
    this.buildInfoHeaderArtifacts = buildInfoHeaderArtifacts;
    return this;
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setCacheKeyInputs(NestedSet<Artifact> cacheKeyInputs) {
    this.cacheKeyInputs = cacheKeyInputs;
    return this;
  }

  public PathFragment getRealOutputFilePath() {
    return outputFile.getExecPath();
  }

  ActionEnvironment getActionEnvironment() {
    return configuration.getActionEnvironment();
  }

  @CanIgnoreReturnValue
  public CppCompileActionBuilder setAdditionalPrunableHeaders(
      NestedSet<Artifact> additionalPrunableHeaders) {
    this.additionalPrunableHeaders = Preconditions.checkNotNull(additionalPrunableHeaders);
    return this;
  }

  ImmutableList<PathFragment> getBuiltinIncludeDirectories() throws EvalException {
    return ccToolchain.getBuiltInIncludeDirectories();
  }

  public boolean shouldCompileHeaders() {
    Preconditions.checkNotNull(featureConfiguration);
    return CcToolchainProvider.shouldProcessHeaders(featureConfiguration, cppConfiguration);
  }
}
