// 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.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.CcCompilationOutputsApi;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.LinkedHashSet;
import java.util.Set;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;

/** A structured representation of the compilation outputs of a C++ rule. */
public class CcCompilationOutputs implements CcCompilationOutputsApi<Artifact> {
  public static final CcCompilationOutputs EMPTY = builder().build();

  /**
   * All .o files built by the target.
   */
  private final ImmutableList<Artifact> objectFiles;

  /**
   * All .pic.o files built by the target.
   */
  private final ImmutableList<Artifact> picObjectFiles;

  /**
   * Maps all .o bitcode files coming from a ThinLTO C(++) compilation under our control to
   * information needed by the LTO indexing and backend steps.
   */
  private final LtoCompilationContext ltoCompilationContext;

  /**
   * All .dwo files built by the target, corresponding to .o outputs.
   */
  private final ImmutableList<Artifact> dwoFiles;

  /**
   * All .pic.dwo files built by the target, corresponding to .pic.o outputs.
   */
  private final ImmutableList<Artifact> picDwoFiles;

  /** All .gcno files built by the target, corresponding to .o outputs. */
  private final ImmutableList<Artifact> gcnoFiles;

  /** All .pic.gcno files built by the target, corresponding to .pic.gcno outputs. */
  private final ImmutableList<Artifact> picGcnoFiles;

  /**
   * All artifacts that are created if "--save_temps" is true.
   */
  private final NestedSet<Artifact> temps;

  /**
   * All token .h.processed files created when preprocessing or parsing headers.
   */
  private final ImmutableList<Artifact> headerTokenFiles;

  private CcCompilationOutputs(
      ImmutableList<Artifact> objectFiles,
      ImmutableList<Artifact> picObjectFiles,
      LtoCompilationContext ltoCompilationContext,
      ImmutableList<Artifact> dwoFiles,
      ImmutableList<Artifact> picDwoFiles,
      ImmutableList<Artifact> gcnoFiles,
      ImmutableList<Artifact> picGcnoFiles,
      NestedSet<Artifact> temps,
      ImmutableList<Artifact> headerTokenFiles) {
    this.objectFiles = objectFiles;
    this.picObjectFiles = picObjectFiles;
    this.ltoCompilationContext = ltoCompilationContext;
    this.dwoFiles = dwoFiles;
    this.picDwoFiles = picDwoFiles;
    this.gcnoFiles = gcnoFiles;
    this.picGcnoFiles = picGcnoFiles;
    this.temps = temps;
    this.headerTokenFiles = headerTokenFiles;
  }

  /**
   * Returns whether this set of outputs has any object or .pic object files.
   */
  public boolean isEmpty() {
    return picObjectFiles.isEmpty() && objectFiles.isEmpty();
  }

  /**
   * Returns an unmodifiable view of the .o or .pic.o files set.
   *
   * @param usePic whether to return .pic.o files
   */
  public ImmutableList<Artifact> getObjectFiles(boolean usePic) {
    return usePic ? picObjectFiles : objectFiles;
  }

  @Override
  public Sequence<Artifact> getStarlarkObjects() throws EvalException {
    return StarlarkList.immutableCopyOf(getObjectFiles(/* usePic= */ false));
  }

  @Override
  public Sequence<Artifact> getStarlarkPicObjects() throws EvalException {
    return StarlarkList.immutableCopyOf(getObjectFiles(/* usePic= */ true));
  }

  @Override
  public Depset getStarlarkTemps(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getTemps());
  }

  @Override
  public Depset getStarlarkFilesToCompile(
      boolean parseHeaders, boolean usePic, StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return Depset.of(Artifact.TYPE, getFilesToCompile(parseHeaders, usePic));
  }

  @Override
  public Sequence<Artifact> getStarlarkHeaderTokens(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getHeaderTokenFiles());
  }

  /** Returns information about bitcode object files resulting from compilation. */
  public LtoCompilationContext getLtoCompilationContext() {
    return ltoCompilationContext;
  }

  @Override
  public LtoCompilationContext getLtoCompilationContextForStarlark(StarlarkThread thread)
      throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return ltoCompilationContext;
  }

  @Override
  public Sequence<Artifact> getStarlarkDwoFiles(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getDwoFiles());
  }

  @Override
  public Sequence<Artifact> getStarlarkPicDwoFiles(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getPicDwoFiles());
  }

  /**
   * Returns an unmodifiable view of the .dwo files set.
   */
  public ImmutableList<Artifact> getDwoFiles() {
    return dwoFiles;
  }

  /**
   * Returns an unmodifiable view of the .pic.dwo files set.
   */
  public ImmutableList<Artifact> getPicDwoFiles() {
    return picDwoFiles;
  }

  @Override
  public Sequence<Artifact> getStarlarkGcnoFiles(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getGcnoFiles());
  }

  @Override
  public Sequence<Artifact> getStarlarkPicGcnoFiles(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getPicGcnoFiles());
  }

  /** Returns an unmodifiable view of the .gcno files set. */
  public ImmutableList<Artifact> getGcnoFiles() {
    return gcnoFiles;
  }

  /** Returns an unmodifiable view of the .pic.gcno files set. */
  public ImmutableList<Artifact> getPicGcnoFiles() {
    return picGcnoFiles;
  }

  /**
   * Returns an unmodifiable view of the temp files set.
   */
  public NestedSet<Artifact> getTemps() {
    return temps;
  }

  /**
   * Returns an unmodifiable view of the .h.processed files.
   */
  public Iterable<Artifact> getHeaderTokenFiles() {
    return headerTokenFiles;
  }

  /** Returns the output files that are considered "compiled" by this C++ compile action. */
  NestedSet<Artifact> getFilesToCompile(boolean parseHeaders, boolean usePic) {
    NestedSetBuilder<Artifact> files = NestedSetBuilder.stableOrder();
    files.addAll(getObjectFiles(usePic));
    if (parseHeaders) {
      files.addAll(getHeaderTokenFiles());
    }
    return files.build();
  }

  /** Creates a new builder. */
  public static Builder builder() {
    return new Builder();
  }

  /** Builder for CcCompilationOutputs. */
  public static final class Builder {
    private final Set<Artifact> objectFiles = new LinkedHashSet<>();
    private final Set<Artifact> picObjectFiles = new LinkedHashSet<>();
    private final LtoCompilationContext.Builder ltoCompilationContext =
        new LtoCompilationContext.Builder();
    private final Set<Artifact> dwoFiles = new LinkedHashSet<>();
    private final Set<Artifact> picDwoFiles = new LinkedHashSet<>();
    private final Set<Artifact> gcnoFiles = new LinkedHashSet<>();
    private final Set<Artifact> picGcnoFiles = new LinkedHashSet<>();
    private final NestedSetBuilder<Artifact> temps = NestedSetBuilder.stableOrder();
    private final Set<Artifact> headerTokenFiles = new LinkedHashSet<>();

    private Builder() {
      // private to avoid class initialization deadlock between this class and its outer class
    }

    public CcCompilationOutputs build() {
      return new CcCompilationOutputs(
          ImmutableList.copyOf(objectFiles),
          ImmutableList.copyOf(picObjectFiles),
          ltoCompilationContext.build(),
          ImmutableList.copyOf(dwoFiles),
          ImmutableList.copyOf(picDwoFiles),
          ImmutableList.copyOf(gcnoFiles),
          ImmutableList.copyOf(picGcnoFiles),
          temps.build(),
          ImmutableList.copyOf(headerTokenFiles));
    }

    @CanIgnoreReturnValue
    public Builder merge(CcCompilationOutputs outputs) {
      this.objectFiles.addAll(outputs.objectFiles);
      this.picObjectFiles.addAll(outputs.picObjectFiles);
      this.dwoFiles.addAll(outputs.dwoFiles);
      this.picDwoFiles.addAll(outputs.picDwoFiles);
      this.gcnoFiles.addAll(outputs.gcnoFiles);
      this.picGcnoFiles.addAll(outputs.picGcnoFiles);
      this.temps.addTransitive(outputs.temps);
      this.headerTokenFiles.addAll(outputs.headerTokenFiles);
      this.ltoCompilationContext.addAll(outputs.ltoCompilationContext);
      return this;
    }

    /** Adds an object file. */
    @CanIgnoreReturnValue
    public Builder addObjectFile(Artifact artifact) {
      // We skip file extension checks for TreeArtifacts because they represent directory artifacts
      // without a file extension.
      Preconditions.checkArgument(
          artifact.isTreeArtifact() || Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
      objectFiles.add(artifact);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addObjectFiles(Iterable<Artifact> artifacts) {
      for (Artifact artifact : artifacts) {
        Preconditions.checkArgument(
            artifact.isTreeArtifact() || Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
      }
      Iterables.addAll(objectFiles, artifacts);
      return this;
    }

    /** Adds a pic object file. */
    @CanIgnoreReturnValue
    public Builder addPicObjectFile(Artifact artifact) {
      picObjectFiles.add(artifact);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addLtoBitcodeFile(
        Artifact fullBitcode, Artifact ltoIndexingBitcode, ImmutableList<String> copts) {
      ltoCompilationContext.addBitcodeFile(fullBitcode, ltoIndexingBitcode, copts);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addLtoCompilationContext(LtoCompilationContext ltoCompilationContext) {
      this.ltoCompilationContext.addAll(ltoCompilationContext);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addPicObjectFiles(Iterable<Artifact> artifacts) {
      for (Artifact artifact : artifacts) {
        Preconditions.checkArgument(
            artifact.isTreeArtifact() || Link.OBJECT_FILETYPES.matches(artifact.getFilename()));
      }

      Iterables.addAll(picObjectFiles, artifacts);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addDwoFile(Artifact artifact) {
      dwoFiles.add(artifact);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addPicDwoFile(Artifact artifact) {
      picDwoFiles.add(artifact);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addGcnoFile(Artifact artifact) {
      gcnoFiles.add(artifact);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addPicGcnoFile(Artifact artifact) {
      picGcnoFiles.add(artifact);
      return this;
    }

    /** Adds temp files. */
    @CanIgnoreReturnValue
    public Builder addTemps(Iterable<Artifact> artifacts) {
      temps.addAll(artifacts);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addHeaderTokenFile(Artifact artifact) {
      headerTokenFiles.add(artifact);
      return this;
    }
  }
}
