// 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.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.devtools.build.lib.analysis.ExtraActionUtils.createExtraActionProvider;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.ActionConflictException;
import com.google.devtools.build.lib.actions.Actions;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.config.CoreOptions;
import com.google.devtools.build.lib.analysis.starlark.StarlarkApiProvider;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.Provider;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.TreeMap;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.Starlark;

/**
 * Extra information about a configured target computed on request of a dependent.
 *
 * <p>Analogous to {@link ConfiguredTarget}: contains a bunch of transitive info providers, which
 * are merged with the providers of the associated configured target before they are passed to the
 * configured target factories that depend on the configured target to which this aspect is added.
 *
 * <p>Aspects are created alongside configured targets on request from dependents.
 *
 * <p>For more information about aspects, see {@link
 * com.google.devtools.build.lib.packages.AspectClass}.
 *
 * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
 * @see com.google.devtools.build.lib.packages.AspectClass
 */
public interface ConfiguredAspect extends ProviderCollection {

  ImmutableList<ActionAnalysisMetadata> getActions();

  /** Returns the providers created by the aspect. */
  TransitiveInfoProviderMap getProviders();

  @Override
  @Nullable
  default <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {
    AnalysisUtils.checkProvider(providerClass);
    return getProviders().getProvider(providerClass);
  }

  @Override
  default Info get(Provider.Key key) {
    return getProviders().get(key);
  }

  @Override
  default Object get(String legacyKey) {
    if (OutputGroupInfo.STARLARK_NAME.equals(legacyKey)) {
      return get(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey());
    }
    return getProviders().get(legacyKey);
  }

  static ConfiguredAspect forAlias(ConfiguredAspect real) {
    return new BasicConfiguredAspect(real.getActions(), real.getProviders());
  }

  static ConfiguredAspect forNonapplicableTarget() {
    return new BasicConfiguredAspect(
        ImmutableList.of(), new TransitiveInfoProviderMapBuilder().build());
  }

  static Builder builder(RuleContext ruleContext) {
    return new Builder(ruleContext);
  }

  /** Builder for {@link ConfiguredAspect}. */
  final class Builder {
    private final TransitiveInfoProviderMapBuilder providers =
        new TransitiveInfoProviderMapBuilder();
    private final TreeMap<String, NestedSetBuilder<Artifact>> outputGroupBuilders = new TreeMap<>();
    private final RuleContext ruleContext;

    public Builder(RuleContext ruleContext) {
      this.ruleContext = ruleContext;
    }

    @CanIgnoreReturnValue
    public <T extends TransitiveInfoProvider> Builder addProvider(
        Class<? extends T> providerClass, T provider) {
      checkNotNull(provider);
      checkProviderClass(providerClass);
      providers.put(providerClass, provider);
      return this;
    }

    /** Adds a provider to the aspect. */
    @CanIgnoreReturnValue
    public Builder addProvider(TransitiveInfoProvider provider) {
      checkNotNull(provider);
      addProvider(TransitiveInfoProviderEffectiveClassHelper.get(provider), provider);
      return this;
    }

    private static void checkProviderClass(Class<? extends TransitiveInfoProvider> providerClass) {
      checkNotNull(providerClass);
    }

    /** Adds a set of files to an output group. */
    @CanIgnoreReturnValue
    public Builder addOutputGroup(String name, NestedSet<Artifact> artifacts) {
      outputGroupBuilders
          .computeIfAbsent(name, k -> NestedSetBuilder.stableOrder())
          .addTransitive(artifacts);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addStarlarkTransitiveInfo(String name, Object value) {
      providers.put(name, value);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addStarlarkDeclaredProvider(Info declaredProvider) throws EvalException {
      Provider constructor = declaredProvider.getProvider();
      if (!constructor.isExported()) {
        throw Starlark.errorf(
            "aspect function returned an instance of a provider (defined at %s) that is not a"
                + " global",
            constructor.getLocation());
      }
      addDeclaredProvider(declaredProvider);
      return this;
    }

    private void addDeclaredProvider(Info declaredProvider) {
      providers.put(declaredProvider);
    }

    @CanIgnoreReturnValue
    public Builder addNativeDeclaredProvider(Info declaredProvider) {
      Provider constructor = declaredProvider.getProvider();
      Preconditions.checkState(constructor.isExported());
      addDeclaredProvider(declaredProvider);
      return this;
    }

    @Nullable
    public ConfiguredAspect build() throws ActionConflictException, InterruptedException {
      if (!outputGroupBuilders.isEmpty()) {
        if (providers.contains(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey())) {
          throw new IllegalStateException(
              "OutputGroupInfo was provided explicitly; do not use addOutputGroup");
        }
        addDeclaredProvider(OutputGroupInfo.fromBuilders(outputGroupBuilders));
      }

      // Only add {@link ExtraActionProvider} if extra action listeners are applied
      if (!ruleContext.getConfiguration().getActionListeners().isEmpty()) {
        addProvider(
            createExtraActionProvider(
                /* actionsWithoutExtraAction= */ ImmutableSet.of(), ruleContext));
      }

      AnalysisEnvironment analysisEnvironment = ruleContext.getAnalysisEnvironment();
      ImmutableList<ActionAnalysisMetadata> actions = analysisEnvironment.getRegisteredActions();
      try {
        Actions.assignOwnersAndThrowIfConflictToleratingSharedActions(
            analysisEnvironment.getActionKeyContext(), actions, ruleContext.getOwner());
      } catch (Actions.ArtifactGeneratedByOtherRuleException e) {
        ruleContext.ruleError(e.getMessage());
        return null;
      }

      maybeAddRequiredConfigFragmentsProvider();

      TransitiveInfoProviderMap providerMap = providers.build();

      // Initialize every StarlarkApiProvider
      for (int i = 0; i < providerMap.getProviderCount(); i++) {
        Object obj = providerMap.getProviderInstanceAt(i);
        if (obj instanceof StarlarkApiProvider starlarkApiProvider) {
          starlarkApiProvider.init(providerMap);
        }
      }

      return new BasicConfiguredAspect(actions, providerMap);
    }

    /**
     * Adds {@link RequiredConfigFragmentsProvider} if {@link
     * CoreOptions#includeRequiredConfigFragmentsProvider} isn't {@link
     * CoreOptions.IncludeConfigFragmentsEnum#OFF} and if the provider was not already added.
     *
     * <p>See {@link com.google.devtools.build.lib.analysis.config.RequiredFragmentsUtil} for a
     * description of the meaning of this provider's content. That class contains methods that
     * populate the results of {@link RuleContext#getRequiredConfigFragments}.
     */
    private void maybeAddRequiredConfigFragmentsProvider() {
      if (ruleContext.shouldIncludeRequiredConfigFragmentsProvider()
          && !providers.contains(RequiredConfigFragmentsProvider.class)) {
        addProvider(ruleContext.getRequiredConfigFragments());
      }
    }
  }

  /** Basic implementation of {@link ConfiguredAspect}. */
  static class BasicConfiguredAspect implements ConfiguredAspect {
    /**
     * Operations accessing actions, for example, executing them, should be performed in the same
     * Bazel instance that constructs the {@code ConfiguredAspect} instance and not on a Bazel
     * instance that retrieves it remotely using deserialization.
     */
    @Nullable // Null when deserialized.
    private final transient ImmutableList<ActionAnalysisMetadata> actions;

    private final TransitiveInfoProviderMap providers;

    private BasicConfiguredAspect(
        ImmutableList<ActionAnalysisMetadata> actions, TransitiveInfoProviderMap providers) {
      this.actions = actions;
      this.providers = providers;
    }

    @Override
    public ImmutableList<ActionAnalysisMetadata> getActions() {
      return checkNotNull(actions, "actions are not available on deserialized instances");
    }

    @Override
    public TransitiveInfoProviderMap getProviders() {
      return providers;
    }

    @Override
    public String toString() {
      return toStringHelper(this).add("actions", actions).add("providers", providers).toString();
    }
  }
}
