// Copyright 2017 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.config;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.config.transitions.ComposingTransition;
import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
import com.google.devtools.build.lib.analysis.config.transitions.NullTransition;
import com.google.devtools.build.lib.analysis.config.transitions.PatchTransition;
import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
import com.google.devtools.build.lib.packages.InputFile;
import com.google.devtools.build.lib.packages.PackageGroup;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleTransitionFactory;
import com.google.devtools.build.lib.packages.Target;
import javax.annotation.Nullable;

/**
 * Tool for evaluating which {@link ConfigurationTransition}(s) should be applied to given targets.
 *
 * <p>For the work of turning these transitions into actual configurations, see {@link
 * ConfigurationResolver}.
 *
 * <p>This is the "generic engine" for configuration selection. It doesn't know anything about
 * specific rules or their requirements. Rule writers decide those with appropriately placed {@link
 * PatchTransition} declarations. This class then processes those declarations to determine final
 * transitions.
 */
public final class TransitionResolver {
  /**
   * Given a parent rule and configuration depending on a child through an attribute, determines
   * the configuration the child should take.
   *
   * @param fromConfig the parent rule's configuration
   * @param fromRule the parent rule
   * @param attribute the attribute creating the dependency (e.g. "srcs")
   * @param toTarget the child target (which may or may not be a rule)
   * @param attributeMap the attributes of the rule
   * @param trimmingTransitionFactory the transition factory used to trim rules (note: this is a
   *     temporary feature; see the corresponding methods in ConfiguredRuleClassProvider)
   *
   * @return the child's configuration, expressed as a diff from the parent's configuration. This
   *     is either a {@link PatchTransition} or {@link SplitTransition}.
   */
  public static ConfigurationTransition evaluateTransition(
      BuildConfiguration fromConfig,
      final Rule fromRule,
      final Attribute attribute,
      final Target toTarget,
      ConfiguredAttributeMapper attributeMap,
      @Nullable RuleTransitionFactory trimmingTransitionFactory) {

    // I. Input files and package groups have no configurations. We don't want to duplicate them.
    if (usesNullConfiguration(toTarget)) {
      return NullTransition.INSTANCE;
    }

    // II. Host configurations never switch to another. All prerequisites of host targets have the
    // same host configuration.
    if (fromConfig.isHostConfiguration()) {
      return NoTransition.INSTANCE;
    }

    // Make sure config_setting dependencies are resolved in the referencing rule's configuration,
    // unconditionally. For example, given:
    //
    // genrule(
    //     name = 'myrule',
    //     tools = select({ '//a:condition': [':sometool'] })
    //
    // all labels in "tools" get resolved in the host configuration (since the "tools" attribute
    // declares a host configuration transition). We want to explicitly exclude configuration labels
    // from these transitions, since their *purpose* is to do computation on the owning
    // rule's configuration.
    // TODO(bazel-team): don't require special casing here. This is far too hackish.
    if (toTarget instanceof Rule && ((Rule) toTarget).getRuleClassObject().isConfigMatcher()) {
      // TODO(gregce): see if this actually gets called
      return NoTransition.INSTANCE;
    }

    // The current transition to apply. When multiple transitions are requested, this is a
    // ComposingTransition, which encapsulates them into a single object so calling code
    // doesn't need special logic for combinations.
    ConfigurationTransition currentTransition = NoTransition.INSTANCE;

    // TODO(gregce): make the below transitions composable (i.e. take away the "else" clauses).
    // The "else" is a legacy restriction from static configurations.
    if (attribute.hasSplitConfigurationTransition()) {
      currentTransition = split(currentTransition, attribute.getSplitTransition(attributeMap));
    } else {
      // III. Attributes determine configurations. The configuration of a prerequisite is determined
      // by the attribute.
      currentTransition = composeTransitions(currentTransition,
          attribute.getConfigurationTransition());
    }

    // IV. Applies any rule transitions associated with the dep target and composes their
    // transitions with a passed-in existing transition.
    currentTransition = applyRuleTransition(currentTransition, toTarget);

    // V. Applies a transition to trim the result and returns it. (note: this is a temporary
    // feature; see the corresponding methods in ConfiguredRuleClassProvider)
    return applyTransitionFromFactory(currentTransition, toTarget, trimmingTransitionFactory);
  }

  /**
   * Same as evaluateTransition except does not check for transitions coming from parents and
   * enables support for rule-triggered top-level configuration hooks.
   */
  public static ConfigurationTransition evaluateTopLevelTransition(
      TargetAndConfiguration targetAndConfig,
      @Nullable RuleTransitionFactory trimmingTransitionFactory) {
    Target target = targetAndConfig.getTarget();
    BuildConfiguration fromConfig = targetAndConfig.getConfiguration();

    // Top-level transitions (chosen by configuration fragments):
    ConfigurationTransition topLevelTransition = fromConfig.topLevelConfigurationHook(target);
    if (topLevelTransition == null) {
      topLevelTransition = NoTransition.INSTANCE;
    }

    // Rule class transitions (chosen by rule class definitions):
    if (target.getAssociatedRule() == null) {
      return topLevelTransition;
    }
    ConfigurationTransition ruleTransition = applyRuleTransition(topLevelTransition, target);
    ConfigurationTransition trimmingTransition =
        applyTransitionFromFactory(ruleTransition, target, trimmingTransitionFactory);
    return trimmingTransition;
  }

  /**
   * Returns true if the given target should have a null configuration. This method is the
   * "source of truth" for this determination.
   */
  public static boolean usesNullConfiguration(Target target) {
    return target instanceof InputFile || target instanceof PackageGroup;
  }

  /**
   * Composes two transitions together efficiently.
   */
  public static ConfigurationTransition composeTransitions(ConfigurationTransition transition1,
      ConfigurationTransition transition2) {
    Preconditions.checkNotNull(transition1);
    Preconditions.checkNotNull(transition2);
    if (isFinal(transition1) || transition2 == NoTransition.INSTANCE) {
      return transition1;
    } else if (isFinal(transition2) || transition1 == NoTransition.INSTANCE) {
      // When the second transition is a HOST transition, there's no need to compose. But this also
      // improves performance: host transitions are common, and ConfiguredTargetFunction has special
      // optimized logic to handle them. If they were buried in the last segment of a
      // ComposingTransition, those optimizations wouldn't trigger.
      return transition2;
    } else {
      return new ComposingTransition(transition1, transition2);
    }
  }

  /**
   * Returns true if once the given transition is applied to a dep no followup transitions should
   * be composed after it.
   */
  private static boolean isFinal(ConfigurationTransition transition) {
    return (transition == NullTransition.INSTANCE
        || transition == HostTransition.INSTANCE);
  }

  /**
   * Applies the given split and composes it after an existing transition.
   */
  private static ConfigurationTransition split(ConfigurationTransition currentTransition,
      SplitTransition split) {
    Preconditions.checkState(currentTransition != NullTransition.INSTANCE,
        "cannot apply splits after null transitions (null transitions are expected to be final)");
    Preconditions.checkState(currentTransition != HostTransition.INSTANCE,
        "cannot apply splits after host transitions (host transitions are expected to be final)");
    return composeTransitions(currentTransition, split);
  }

  /**
   * @param currentTransition a pre-existing transition to be composed with
   * @param toTarget target whose associated rule's incoming transition should be applied
   */
  private static ConfigurationTransition applyRuleTransition(
      ConfigurationTransition currentTransition, Target toTarget) {
    Rule associatedRule = toTarget.getAssociatedRule();
    RuleTransitionFactory transitionFactory =
        associatedRule.getRuleClassObject().getTransitionFactory();
    return applyTransitionFromFactory(currentTransition, toTarget, transitionFactory);
  }

  /**
   * @param currentTransition a pre-existing transition to be composed with
   * @param toTarget target whose associated rule's incoming transition should be applied
   * @param transitionFactory a rule transition factory to apply, or null to do nothing
   */
  private static ConfigurationTransition applyTransitionFromFactory(
      ConfigurationTransition currentTransition,
      Target toTarget,
      @Nullable RuleTransitionFactory transitionFactory) {
    if (isFinal(currentTransition)) {
      return currentTransition;
    }
    if (transitionFactory != null) {
      return composeTransitions(
          currentTransition, transitionFactory.buildTransitionFor(toTarget.getAssociatedRule()));
    }
    return currentTransition;
  }
}
