// 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.transitions;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.util.Map;
import java.util.Objects;

/**
 * A configuration transition that composes two other transitions in an ordered sequence.
 *
 * <p>Example:
 *
 * <pre>
 *   transition1: { someSetting = $oldVal + " foo" }
 *   transition2: { someSetting = $oldVal + " bar" }
 *   ComposingTransition(transition1, transition2): { someSetting = $oldVal + " foo bar" }
 * </pre>
 */
@AutoCodec
public class ComposingTransition implements ConfigurationTransition {
  private ConfigurationTransition transition1;
  private ConfigurationTransition transition2;

  /**
   * Creates a {@link ComposingTransition} that applies the sequence: {@code fromOptions ->
   * transition1 -> transition2 -> toOptions }.
   */
  @AutoCodec.Instantiator
  ComposingTransition(ConfigurationTransition transition1, ConfigurationTransition transition2) {
    this.transition1 = transition1;
    this.transition2 = transition2;
  }

  @Override
  public Map<String, BuildOptions> apply(BuildOptions buildOptions, EventHandler eventHandler) {
    ImmutableMap.Builder<String, BuildOptions> toOptions = ImmutableMap.builder();
    for (Map.Entry<String, BuildOptions> entry1 :
        transition1.apply(buildOptions, eventHandler).entrySet()) {
      for (Map.Entry<String, BuildOptions> entry2 :
          transition2.apply(entry1.getValue(), eventHandler).entrySet()) {
        toOptions.put(composeKeys(entry1.getKey(), entry2.getKey()), entry2.getValue());
      }
    }
    return toOptions.build();
  }

  @Override
  public String reasonForOverride() {
    return "Basic abstraction for combining other transitions";
  }

  @Override
  public String getName() {
    return "(" + transition1.getName() + " + " + transition2.getName() + ")";
  }

  // Override to allow recursive visiting.
  @Override
  public <E extends Exception> void visit(Visitor<E> visitor) throws E {
    this.transition1.visit(visitor);
    this.transition2.visit(visitor);
  }

  @Override
  public int hashCode() {
    return Objects.hash(transition1, transition2);
  }

  @Override
  public boolean equals(Object other) {
    return other instanceof ComposingTransition
        && ((ComposingTransition) other).transition1.equals(this.transition1)
        && ((ComposingTransition) other).transition2.equals(this.transition2);
  }

  /**
   * Creates a {@link ComposingTransition} that applies the sequence: {@code fromOptions ->
   * transition1 -> transition2 -> toOptions }.
   *
   * <p>Note that this method checks for transitions that cannot be composed, such as if one of the
   * transitions is {@link NoTransition} or the host transition, and returns an efficiently composed
   * transition.
   */
  public static ConfigurationTransition of(
      ConfigurationTransition transition1, ConfigurationTransition transition2) {
    Preconditions.checkNotNull(transition1);
    Preconditions.checkNotNull(transition2);

    if (isFinal(transition1)) {
      // Since no other transition can be composed with transition1, use it directly.
      return transition1;
    } else if (transition1 == NoTransition.INSTANCE) {
      // Since transition1 causes no changes, use transition2 directly.
      return transition2;
    }

    if (transition2 == NoTransition.INSTANCE) {
      // Since transition2 causes no changes, use transition 1 directly.
      return transition1;
    } else if (isFinal(transition2)) {
      // When the second transition is null or 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;
    }

    return new ComposingTransition(transition1, transition2);
  }

  private static boolean isFinal(ConfigurationTransition transition) {
    return transition == NullTransition.INSTANCE || transition.isHostTransition();
  }

  /**
   * Composes a new key out of two given keys. Composing two split transitions is not allowed at the
   * moment, so what this essentially does are (1) make sure not both transitions are split and (2)
   * choose one from a split transition, if there's any, or return {@code PATCH_TRANSITION_KEY),
   * if there isn't.
   */
  private String composeKeys(String key1, String key2) {
    if (!key1.equals(PATCH_TRANSITION_KEY)) {
      if (!key2.equals(PATCH_TRANSITION_KEY)) {
        throw new IllegalStateException(
            String.format(
                "can't compose two split transitions %s and %s",
                transition1.getName(), transition2.getName()));
      }
      return key1;
    }
    return key2;
  }
}
