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

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LicensesProvider;
import com.google.devtools.build.lib.analysis.LicensesProviderImpl;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider;
import com.google.devtools.build.lib.analysis.TargetContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.Provider;
import javax.annotation.Nullable;
import net.starlark.java.eval.Dict;
import net.starlark.java.eval.Printer;

/** A ConfiguredTarget for an OutputFile. */
@Immutable
public final class OutputFileConfiguredTarget extends FileConfiguredTarget {

  private final RuleConfiguredTarget generatingRule;

  public OutputFileConfiguredTarget(
      TargetContext targetContext, Artifact outputArtifact, RuleConfiguredTarget generatingRule) {
    super(targetContext, outputArtifact);
    this.generatingRule = checkNotNull(generatingRule);
    checkArgument(targetContext.getTarget() instanceof OutputFile, targetContext.getTarget());
  }

  public RuleConfiguredTarget getGeneratingRule() {
    return generatingRule;
  }

  @Override
  @Nullable
  public <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {
    P provider = super.getProvider(providerClass);
    if (provider != null) {
      return provider;
    }
    if (providerClass == RequiredConfigFragmentsProvider.class) {
      return generatingRule.getProvider(providerClass);
    }
    return null;
  }

  @Nullable
  @Override
  protected Info rawGetStarlarkProvider(Provider.Key providerKey) {
    // The following Starlark providers do not implement TransitiveInfoProvider and thus may only be
    // requested via this method using a Provider.Key, not via getProvider(Class) above.

    if (providerKey.equals(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR.getKey())) {
      return firstNonNull(
          generatingRule.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR),
          InstrumentedFilesInfo.EMPTY);
    }

    if (providerKey.equals(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey())) {
      // We have an OutputFileConfiguredTarget, so the generating rule must have OutputGroupInfo.
      NestedSet<Artifact> validationOutputs =
          generatingRule
              .get(OutputGroupInfo.STARLARK_CONSTRUCTOR)
              .getOutputGroup(OutputGroupInfo.VALIDATION);
      if (!validationOutputs.isEmpty()) {
        return OutputGroupInfo.singleGroup(OutputGroupInfo.VALIDATION, validationOutputs);
      }
    }

    return null;
  }

  @Override
  public Dict<String, Object> getProvidersDictForQuery() {
    Dict.Builder<String, Object> dict = Dict.builder();
    dict.putAll(super.getProvidersDictForQuery());
    addStarlarkProviderIfPresent(dict, InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
    addStarlarkProviderIfPresent(dict, OutputGroupInfo.STARLARK_CONSTRUCTOR);
    addNativeProviderFromRuleIfPresent(dict, RequiredConfigFragmentsProvider.class);
    return dict.buildImmutable();
  }

  private void addStarlarkProviderIfPresent(Dict.Builder<String, Object> dict, Provider provider) {
    Info info = rawGetStarlarkProvider(provider.getKey());
    if (info != null) {
      tryAddProviderForQuery(dict, provider.getKey(), info);
    }
  }

  private void addNativeProviderFromRuleIfPresent(
      Dict.Builder<String, Object> dict, Class<? extends TransitiveInfoProvider> providerClass) {
    TransitiveInfoProvider provider = generatingRule.getProvider(providerClass);
    if (provider != null) {
      tryAddProviderForQuery(dict, providerClass, provider);
    }
  }

  @Override
  public NestedSet<TargetLicense> getTransitiveLicenses() {
    return getLicencesProviderFromGeneratingRule().getTransitiveLicenses();
  }

  @Override
  public TargetLicense getOutputLicenses() {
    return getLicencesProviderFromGeneratingRule().getOutputLicenses();
  }

  @Override
  public boolean hasOutputLicenses() {
    return getLicencesProviderFromGeneratingRule().hasOutputLicenses();
  }

  private LicensesProvider getLicencesProviderFromGeneratingRule() {
    return firstNonNull(
        generatingRule.getProvider(LicensesProvider.class), LicensesProviderImpl.EMPTY);
  }

  @Override
  public void repr(Printer printer) {
    printer.append("<output file target " + getLabel() + ">");
  }
}
