// 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();

    // Rule class transitions (chosen by rule class definitions):
    if (target.getAssociatedRule() == null) {
      return NoTransition.INSTANCE;
    }
    ConfigurationTransition ruleTransition = applyRuleTransition(NoTransition.INSTANCE, 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;
  }
}
