// Copyright 2015 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.collect.Lists;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.starlark.StarlarkRuleContext;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.ExtraLinkTimeLibrary.BuildLibraryOutput;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.starlark.java.annot.Param;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Sequence;
import net.starlark.java.eval.StarlarkList;
import net.starlark.java.eval.StarlarkThread;
import net.starlark.java.eval.StarlarkValue;
import net.starlark.java.eval.Tuple;

/**
 * A list of extra libraries to include in a link. These are non-C++ libraries that are built from
 * inputs gathered from all the dependencies. The dependencies have no way to coordinate, so each
 * one will add an ExtraLinkTimeLibrary to its CcLinkParams. ExtraLinkTimeLibrary is an interface,
 * and all ExtraLinkTimeLibrary objects of the same class will be gathered together.
 */
public final class ExtraLinkTimeLibraries implements StarlarkValue {
  /**
   * We can have multiple different kinds of lists of libraries to include
   * at link time.  We map from the class type to an actual instance.
   */
  private final Collection<ExtraLinkTimeLibrary> extraLibraries;

  private ExtraLinkTimeLibraries(Collection<ExtraLinkTimeLibrary> extraLibraries) {
    this.extraLibraries = extraLibraries;
  }

  /**
   * Return the set of extra libraries.
   */
  public Collection<ExtraLinkTimeLibrary> getExtraLibraries() {
    return extraLibraries;
  }

  /** Get the set of extra libraries for Starlark. */
  @StarlarkMethod(name = "extra_libraries", documented = false, useStarlarkThread = true)
  public Sequence<ExtraLinkTimeLibrary> getExtraLibrariesForStarlark(StarlarkThread thread)
      throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return StarlarkList.immutableCopyOf(getExtraLibraries());
  }

  public static final Builder builder() {
    return new Builder();
  }

  /**
   * Builder for {@link ExtraLinkTimeLibraries}.
   */
  public static final class Builder {
    private Map<Class<? extends ExtraLinkTimeLibrary>, ExtraLinkTimeLibrary.Builder> libraries =
          new LinkedHashMap<>();

    private Builder() {
      // Nothing to do.
    }

    /**
     * Build a {@link ExtraLinkTimeLibraries} object.
     */
    public ExtraLinkTimeLibraries build() {
      List<ExtraLinkTimeLibrary> extraLibraries = Lists.newArrayList();
      for (ExtraLinkTimeLibrary.Builder builder : libraries.values()) {
        extraLibraries.add(builder.build());
      }
      return new ExtraLinkTimeLibraries(extraLibraries);
    }

    /** Add a transitive dependency. */
    @CanIgnoreReturnValue
    public final Builder addTransitive(ExtraLinkTimeLibraries dep) {
      for (ExtraLinkTimeLibrary depLibrary : dep.getExtraLibraries()) {
        Class<? extends ExtraLinkTimeLibrary> c = depLibrary.getClass();
        libraries.computeIfAbsent(c, k -> depLibrary.getBuilder());
        libraries.get(c).addTransitive(depLibrary);
      }
      return this;
    }

    /** Add a single library to build. */
    @CanIgnoreReturnValue
    public final Builder add(ExtraLinkTimeLibrary b) {
      Class<? extends ExtraLinkTimeLibrary> c = b.getClass();
      libraries.computeIfAbsent(c, k -> b.getBuilder());
      libraries.get(c).addTransitive(b);
      return this;
    }
  }

  public BuildLibraryOutput buildLibraries(
      RuleContext ruleContext, boolean staticMode, boolean forDynamicLibrary)
      throws InterruptedException, RuleErrorException {
    NestedSetBuilder<CcLinkingContext.LinkerInput> linkerInputs = NestedSetBuilder.linkOrder();
    NestedSetBuilder<Artifact> runtimeLibraries = NestedSetBuilder.linkOrder();
    for (ExtraLinkTimeLibrary extraLibrary : getExtraLibraries()) {
      BuildLibraryOutput buildLibraryOutput =
          extraLibrary.buildLibraries(ruleContext, staticMode, forDynamicLibrary);
      linkerInputs.addTransitive(buildLibraryOutput.getLinkerInputs());
      runtimeLibraries.addTransitive(buildLibraryOutput.getRuntimeLibraries());
    }
    return new BuildLibraryOutput(linkerInputs.build(), runtimeLibraries.build());
  }

  @StarlarkMethod(
      name = "build_libraries",
      documented = false,
      useStarlarkThread = true,
      parameters = {
        @Param(name = "ctx", positional = false, named = true),
        @Param(name = "static_mode", positional = false, named = true),
        @Param(name = "for_dynamic_library", positional = false, named = true),
      })
  public Tuple getBuildLibrariesForStarlark(
      StarlarkRuleContext starlarkRuleContext,
      boolean staticMode,
      boolean forDynamicLibrary,
      StarlarkThread thread)
      throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    try {
      BuildLibraryOutput buildLibraryOutput =
          buildLibraries(starlarkRuleContext.getRuleContext(), staticMode, forDynamicLibrary);
      Depset linkerInputs =
          Depset.of(CcLinkingContext.LinkerInput.TYPE, buildLibraryOutput.getLinkerInputs());
      Depset runtimeLibraries = Depset.of(Artifact.TYPE, buildLibraryOutput.getRuntimeLibraries());
      return Tuple.pair(linkerInputs, runtimeLibraries);
    } catch (InterruptedException | RuleErrorException e) {
      throw new EvalException(e);
    }
  }
}
