// 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.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.TransitionFactory;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleTransitionData;
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
 * com.google.devtools.build.lib.analysis.config.transitions.PatchTransition} declarations. This
 * class then processes those declarations to determine final transitions.
 */
public final class TransitionResolver {
  /**
   * Given an original configuration and a base transition, determines the configuration a target
   * should have.
   *
   * @param fromConfig the original configuration
   * @param baseTransition the base configuration transitions computed by this method should be
   *     composed with (the configuration transition of the attribute through which this dependency
   *     happens or {@code NoTransition.INSTANCE} if this is a top-level target)
   * @param toTarget the target whose configuration should be computed (may or may not be a rule)
   * @param trimmingTransitionFactory the transition factory used to trim rules (note: this is a
   *     temporary feature; see the corresponding methods in {@code ConfiguredRuleClassProvider})
   * @return the target's configuration(s), expressed as a diff from the original configuration.
   */
  public static ConfigurationTransition evaluateTransition(
      BuildConfiguration fromConfig,
      ConfigurationTransition baseTransition,
      Target toTarget,
      @Nullable TransitionFactory<RuleTransitionData> trimmingTransitionFactory) {

    // I. The null configuration always remains the null configuration. We could fold this into
    // (III), but NoTransition doesn't work if the source is the null configuration.
    if (fromConfig == null) {
      return NullTransition.INSTANCE;
    }

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

    // III. Host configurations never switch to another. All prerequisites of host targets have the
    // same host configuration.
    if (fromConfig.isHostConfiguration()) {
      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.
    // IV. Apply whatever transition the attribute requires.
    ConfigurationTransition currentTransition = baseTransition;

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

    // VI. 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);
  }

  /**
   * @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();
    TransitionFactory<RuleTransitionData> 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 TransitionFactory<RuleTransitionData> transitionFactory) {
    if (transitionFactory != null) {
      return ComposingTransition.of(
          currentTransition,
          transitionFactory.create(RuleTransitionData.create(toTarget.getAssociatedRule())));
    }
    return currentTransition;
  }
}
