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