// 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 com.google.devtools.build.lib.analysis.AliasProvider.TargetMode;
import com.google.devtools.build.lib.analysis.RuleContext.PrerequisiteValidator;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.FunctionSplitTransitionAllowlist;
import com.google.devtools.build.lib.packages.InputFile;
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.PackageGroup;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;

/**
 * A base implementation of {@link PrerequisiteValidator} that performs common checks based on
 * definitions of what is considered the same logical package and what is considered "experimental"
 * code, which has may have relaxed checks for visibility and deprecation.
 */
public abstract class CommonPrerequisiteValidator implements PrerequisiteValidator {
  @Override
  public void validate(
      RuleContext.Builder contextBuilder,
      ConfiguredTargetAndData prerequisite,
      Attribute attribute) {
    validateDirectPrerequisiteLocation(contextBuilder, prerequisite);
    validateDirectPrerequisiteVisibility(contextBuilder, prerequisite, attribute);
    validateDirectPrerequisiteForTestOnly(contextBuilder, prerequisite);
    validateDirectPrerequisiteForDeprecation(
        contextBuilder, contextBuilder.getRule(), prerequisite, contextBuilder.forAspect());
  }

  /**
   * Returns whether two packages are considered the same for purposes of deprecation warnings.
   * Dependencies within the same package do not print deprecation warnings; a package in the
   * javatests directory may also depend on its corresponding java package without a warning.
   */
  public abstract boolean isSameLogicalPackage(
      PackageIdentifier thisPackage, PackageIdentifier prerequisitePackage);

  /**
   * Returns whether a package is considered experimental. Packages outside of experimental may not
   * depend on packages that are experimental.
   */
  protected abstract boolean packageUnderExperimental(PackageIdentifier packageIdentifier);

  protected abstract boolean checkVisibilityForExperimental(RuleContext.Builder context);

  protected abstract boolean allowExperimentalDeps(RuleContext.Builder context);

  private void validateDirectPrerequisiteVisibility(
      RuleContext.Builder context, ConfiguredTargetAndData prerequisite, Attribute attribute) {
    String attrName = attribute.getName();
    Rule rule = context.getRule();
    Target prerequisiteTarget = prerequisite.getTarget();

    // We don't check the visibility of late-bound attributes, because it would break some
    // features.
    if (!isSameLogicalPackage(
            rule.getLabel().getPackageIdentifier(),
            AliasProvider.getDependencyLabel(prerequisite.getConfiguredTarget())
                .getPackageIdentifier())
        && !Attribute.isLateBound(attrName)) {

      // Determine if we should use the new visibility rules for tools.
      boolean toolCheckAtDefinition = false;
      try {
        toolCheckAtDefinition =
            context
                .getStarlarkSemantics()
                .getBool(
                    BuildLanguageOptions.INCOMPATIBLE_VISIBILITY_PRIVATE_ATTRIBUTES_AT_DEFINITION);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }

      if (!toolCheckAtDefinition
          || !attribute.isImplicit()
          || rule.getRuleClassObject().getRuleDefinitionEnvironmentLabel() == null) {
        // Default check: The attribute must be visible from the target.
        if (!context.isVisible(prerequisite.getConfiguredTarget())) {
          handleVisibilityConflict(context, prerequisite, rule.getLabel());
        }
      } else {
        // For implicit attributes, check if the prerequisite is visible from the location of the
        // rule definition
        Label implicitDefinition = rule.getRuleClassObject().getRuleDefinitionEnvironmentLabel();
        if (!RuleContext.isVisible(implicitDefinition, prerequisite.getConfiguredTarget())) {
          handleVisibilityConflict(context, prerequisite, implicitDefinition);
        }
      }
    }

    if (prerequisiteTarget instanceof PackageGroup) {
      Attribute configuredAttribute = RawAttributeMapper.of(rule).getAttributeDefinition(attrName);
      if (configuredAttribute == null) { // handles aspects
        configuredAttribute = attribute;
      }
      boolean containsPackageSpecificationProvider =
          configuredAttribute
              .getRequiredProviders()
              .getDescription()
              .contains("PackageSpecificationProvider");
      // TODO(plf): Add the PackageSpecificationProvider to the 'visibility' attribute.
      if (!attrName.equals("visibility")
          && !attrName.equals(FunctionSplitTransitionAllowlist.ATTRIBUTE_NAME)
          && !attrName.equals(FunctionSplitTransitionAllowlist.LEGACY_ATTRIBUTE_NAME)
          && !containsPackageSpecificationProvider) {
        context.attributeError(
            attrName,
            "in "
                + attrName
                + " attribute of "
                + rule.getRuleClass()
                + " rule "
                + rule.getLabel()
                + ": "
                + AliasProvider.describeTargetWithAliases(prerequisite, TargetMode.WITH_KIND)
                + " is misplaced here (they are only allowed in the visibility attribute)");
      }
    }
  }

  private void handleVisibilityConflict(
      RuleContext.Builder context, ConfiguredTargetAndData prerequisite, Label rule) {
    if (packageUnderExperimental(rule.getPackageIdentifier())
        && !checkVisibilityForExperimental(context)) {
      return;
    }

    if (!context.getConfiguration().checkVisibility()) {
      String errorMessage =
          String.format(
              "Target '%s' violates visibility of "
                  + "%s. Continuing because --nocheck_visibility is active",
              rule, AliasProvider.describeTargetWithAliases(prerequisite, TargetMode.WITHOUT_KIND));
      context.ruleWarning(errorMessage);
    } else {
      String errorMessage =
          String.format(
              "%s is not visible from target '%s'. Check "
                  + "the visibility declaration of the former target if you think "
                  + "the dependency is legitimate",
              AliasProvider.describeTargetWithAliases(prerequisite, TargetMode.WITHOUT_KIND), rule);

      if (prerequisite.getTarget().getTargetKind().equals(InputFile.targetKind())) {
        errorMessage +=
            ". To set the visibility of that source file target, use the exports_files() function";
      }
      context.ruleError(errorMessage);
    }
  }

  private void validateDirectPrerequisiteLocation(
      RuleContext.Builder context, ConfiguredTargetAndData prerequisite) {
    Rule rule = context.getRule();
    Target prerequisiteTarget = prerequisite.getTarget();
    Label prerequisiteLabel = prerequisiteTarget.getLabel();

    if (packageUnderExperimental(prerequisiteLabel.getPackageIdentifier())
        && !packageUnderExperimental(rule.getLabel().getPackageIdentifier())) {
      String message =
          "non-experimental target '"
              + rule.getLabel()
              + "' depends on experimental target '"
              + prerequisiteLabel
              + "'";
      if (allowExperimentalDeps(context)) {
        context.ruleWarning(
            message + " (ignored due to --experimental_deps_ok;" + " do not submit)");
      } else {
        context.ruleError(
            message
                + " (you may not check in such a dependency,"
                + " though you can test "
                + "against it by passing --experimental_deps_ok)");
      }
    }
  }

  /** Returns whether a deprecation warning should be printed for the prerequisite described. */
  private boolean shouldEmitDeprecationWarningFor(
      String thisDeprecation,
      PackageIdentifier thisPackage,
      String prerequisiteDeprecation,
      PackageIdentifier prerequisitePackage,
      boolean forAspect) {
    // Don't report deprecation edges from javatests to java or within a package;
    // otherwise tests of deprecated code generate nuisance warnings.
    // Don't report deprecation if the current target is also deprecated,
    // or if the current context is evaluating an aspect,
    // as the base target would have already printed the deprecation warnings.
    return (!forAspect
        && prerequisiteDeprecation != null
        && !isSameLogicalPackage(thisPackage, prerequisitePackage)
        && thisDeprecation == null);
  }

  /** Checks if the given prerequisite is deprecated and prints a warning if so. */
  private void validateDirectPrerequisiteForDeprecation(
      RuleErrorConsumer errors,
      Rule rule,
      ConfiguredTargetAndData prerequisite,
      boolean forAspect) {
    Target prerequisiteTarget = prerequisite.getTarget();
    Label prerequisiteLabel = prerequisiteTarget.getLabel();
    PackageIdentifier thatPackage = prerequisiteLabel.getPackageIdentifier();
    PackageIdentifier thisPackage = rule.getLabel().getPackageIdentifier();

    if (prerequisiteTarget instanceof Rule) {
      Rule prerequisiteRule = (Rule) prerequisiteTarget;
      String thisDeprecation =
          NonconfigurableAttributeMapper.of(rule).has("deprecation", Type.STRING)
              ? NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING)
              : null;
      String thatDeprecation =
          NonconfigurableAttributeMapper.of(prerequisiteRule).has("deprecation", Type.STRING)
              ? NonconfigurableAttributeMapper.of(prerequisiteRule).get("deprecation", Type.STRING)
              : null;
      if (shouldEmitDeprecationWarningFor(
          thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
        errors.ruleWarning(
            "target '"
                + rule.getLabel()
                + "' depends on deprecated target '"
                + prerequisiteLabel
                + "': "
                + thatDeprecation);
      }
    }

    if (prerequisiteTarget instanceof OutputFile) {
      Rule generatingRule = ((OutputFile) prerequisiteTarget).getGeneratingRule();
      String thisDeprecation =
          NonconfigurableAttributeMapper.of(rule).get("deprecation", Type.STRING);
      String thatDeprecation =
          NonconfigurableAttributeMapper.of(generatingRule).get("deprecation", Type.STRING);
      if (shouldEmitDeprecationWarningFor(
          thisDeprecation, thisPackage, thatDeprecation, thatPackage, forAspect)) {
        errors.ruleWarning(
            "target '"
                + rule.getLabel()
                + "' depends on the output file "
                + prerequisiteLabel
                + " of a deprecated rule "
                + generatingRule.getLabel()
                + "': "
                + thatDeprecation);
      }
    }
  }

  /** Check that the dependency is not test-only, or the current rule is test-only. */
  private void validateDirectPrerequisiteForTestOnly(
      RuleContext.Builder context, ConfiguredTargetAndData prerequisite) {
    Rule rule = context.getRule();

    if (rule.getRuleClassObject().getAdvertisedProviders().canHaveAnyProvider()) {
      // testonly-ness will be checked directly between the depender and the target of the alias;
      // getTarget() called by the depender will not return the alias rule, but its actual target
      return;
    }

    Target prerequisiteTarget = prerequisite.getTarget();
    PackageIdentifier thisPackage = rule.getLabel().getPackageIdentifier();

    if (isTestOnlyRule(prerequisiteTarget) && !isTestOnlyRule(rule)) {
      String message =
          "non-test target '"
              + rule.getLabel()
              + "' depends on testonly "
              + AliasProvider.describeTargetWithAliases(prerequisite, TargetMode.WITHOUT_KIND)
              + " and doesn't have testonly attribute set";
      if (packageUnderExperimental(thisPackage)) {
        context.ruleWarning(message);
      } else {
        context.ruleError(message);
      }
    }
  }

  private static boolean isTestOnlyRule(Target target) {
    return (target instanceof Rule)
        && NonconfigurableAttributeMapper.of((Rule) target).has("testonly", Type.BOOLEAN)
        && NonconfigurableAttributeMapper.of((Rule) target).get("testonly", Type.BOOLEAN);
  }
}
