// Copyright 2014 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.skyframe;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.MoreObjects;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.skyframe.SkyFunctionName;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * In simple form, a ({@link Label}, {@link BuildConfigurationValue}) pair used to trigger immediate
 * dependency resolution and the rule analysis.
 *
 * <p>In practice, a ({@link Label} and post-transition {@link BuildConfigurationKey}) pair plus a
 * possible execution platform override {@link Label} with special constraints. To elaborate, in
 * order of highest to lowest potential for concern:
 *
 * <p>1. The {@link BuildConfigurationKey} must be post-transition and thus ready for immediate use
 * in dependency resolution and analysis. In practice, this means that if the rule has an
 * incoming-edge transition (cfg in {@link RuleClass}) or there are global trimming transitions,
 * THOSE TRANSITIONS MUST ALREADY BE DONE before creating the key. Failure to do so will lead to
 * build graphs with ConfiguredTarget that have seemingly impossible {@link BuildConfigurationValue}
 * (due to the skipped transitions).
 *
 * <p>2. A build should not request keys with equal ({@link Label}, {@link BuildConfigurationValue})
 * pairs but different execution platform override {@link Label} if the invoked rule will register
 * actions. (This is potentially OK if all outputs of all registered actions incorporate the
 * execution platform in their name unless the build also requests keys without an override that
 * happen to resolve to the same execution platform.) In practice, this issue has not been seen in
 * any 'real' builds; however, pathologically failure could lead to multiple (potentially different)
 * ConfiguredTarget that have the same ({@link Label}, {@link BuildConfigurationValue}) pair.
 *
 * <p>Note that this key may be used to look up the generating action of an artifact.
 *
 * <p>TODO(blaze-configurability-team): Consider just using BuildOptions over a
 * BuildConfigurationKey.
 */
@AutoCodec
public class ConfiguredTargetKey implements ActionLookupKey {
  /**
   * Cache so that the number of ConfiguredTargetKey instances is {@code O(configured targets)} and
   * not {@code O(edges between configured targets)}.
   */
  private static final Interner<ConfiguredTargetKey> interner = BlazeInterners.newWeakInterner();

  private final Label label;
  @Nullable private final BuildConfigurationKey configurationKey;

  private final transient int hashCode;

  ConfiguredTargetKey(Label label, @Nullable BuildConfigurationKey configurationKey, int hashCode) {
    this.label = checkNotNull(label);
    this.configurationKey = configurationKey;
    this.hashCode = hashCode;
  }

  @AutoCodec.VisibleForSerialization
  @AutoCodec.Instantiator
  static ConfiguredTargetKey create(Label label, @Nullable BuildConfigurationKey configurationKey) {
    int hashCode = computeHashCode(label, configurationKey, /*executionPlatformLabel=*/ null);
    return interner.intern(new ConfiguredTargetKey(label, configurationKey, hashCode));
  }

  public Builder toBuilder() {
    return builder()
        .setConfigurationKey(configurationKey)
        .setLabel(label)
        .setExecutionPlatformLabel(getExecutionPlatformLabel());
  }

  @Override
  public final Label getLabel() {
    return label;
  }

  @Override
  public final SkyFunctionName functionName() {
    return SkyFunctions.CONFIGURED_TARGET;
  }

  @Nullable
  public final BuildConfigurationKey getConfigurationKey() {
    return configurationKey;
  }

  @Nullable
  public Label getExecutionPlatformLabel() {
    return null;
  }

  @Override
  public final int hashCode() {
    return hashCode;
  }

  private static int computeHashCode(
      Label label,
      @Nullable BuildConfigurationKey configurationKey,
      @Nullable Label executionPlatformLabel) {
    int configVal = configurationKey == null ? 79 : configurationKey.hashCode();
    int executionPlatformLabelVal =
        executionPlatformLabel == null ? 47 : executionPlatformLabel.hashCode();
    return 31 * label.hashCode() + configVal + executionPlatformLabelVal;
  }

  @Override
  public final boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof ConfiguredTargetKey)) {
      return false;
    }
    ConfiguredTargetKey other = (ConfiguredTargetKey) obj;
    return hashCode == other.hashCode
        && label.equals(other.label)
        && Objects.equals(configurationKey, other.configurationKey)
        && Objects.equals(getExecutionPlatformLabel(), other.getExecutionPlatformLabel());
  }

  public final String prettyPrint() {
    if (label == null) {
      return "null";
    }
    return String.format(
        "%s (%s)",
        label, configurationKey == null ? "null" : configurationKey.getOptions().checksum());
  }

  @Override
  public final String toString() {
    // TODO(b/162809183): consider reverting to less verbose toString when bug is resolved.
    MoreObjects.ToStringHelper helper =
        MoreObjects.toStringHelper(this).add("label", label).add("config", configurationKey);
    if (getExecutionPlatformLabel() != null) {
      helper.add("executionPlatformLabel", getExecutionPlatformLabel());
    }
    return helper.toString();
  }

  @AutoCodec.VisibleForSerialization
  @AutoCodec
  static class ToolchainDependencyConfiguredTargetKey extends ConfiguredTargetKey {
    private static final Interner<ToolchainDependencyConfiguredTargetKey>
        toolchainDependencyConfiguredTargetKeyInterner = BlazeInterners.newWeakInterner();

    private final Label executionPlatformLabel;

    private ToolchainDependencyConfiguredTargetKey(
        Label label,
        @Nullable BuildConfigurationKey configurationKey,
        int hashCode,
        Label executionPlatformLabel) {
      super(label, configurationKey, hashCode);
      this.executionPlatformLabel = checkNotNull(executionPlatformLabel);
    }

    @AutoCodec.VisibleForSerialization
    @AutoCodec.Instantiator
    static ToolchainDependencyConfiguredTargetKey create(
        Label label,
        @Nullable BuildConfigurationKey configurationKey,
        Label executionPlatformLabel) {
      int hashCode = computeHashCode(label, configurationKey, executionPlatformLabel);
      return toolchainDependencyConfiguredTargetKeyInterner.intern(
          new ToolchainDependencyConfiguredTargetKey(
              label, configurationKey, hashCode, executionPlatformLabel));
    }

    @Override
    public final Label getExecutionPlatformLabel() {
      return executionPlatformLabel;
    }
  }

  /** Returns a new {@link Builder} to create instances of {@link ConfiguredTargetKey}. */
  public static Builder builder() {
    return new Builder();
  }

  /** A helper class to create instances of {@link ConfiguredTargetKey}. */
  public static final class Builder {
    private Label label = null;
    private BuildConfigurationKey configurationKey = null;
    private Label executionPlatformLabel = null;

    private Builder() {}

    /** Sets the label for the target. */
    public Builder setLabel(Label label) {
      this.label = label;
      return this;
    }

    /**
     * Sets the {@link ConfiguredTarget} that we want a key for.
     *
     * <p>This sets both the label and configurationKey data.
     */
    public Builder setConfiguredTarget(ConfiguredTarget configuredTarget) {
      setLabel(configuredTarget.getOriginalLabel());
      if (this.configurationKey == null) {
        setConfigurationKey(configuredTarget.getConfigurationKey());
      }
      return this;
    }

    /** Sets the {@link BuildConfigurationValue} for the configured target. */
    public Builder setConfiguration(@Nullable BuildConfigurationValue buildConfiguration) {
      return setConfigurationKey(buildConfiguration == null ? null : buildConfiguration.getKey());
    }

    /** Sets the configuration key for the configured target. */
    public Builder setConfigurationKey(@Nullable BuildConfigurationKey configurationKey) {
      this.configurationKey = configurationKey;
      return this;
    }

    /**
     * Sets the execution platform {@link Label} this configured target should use for toolchain
     * resolution. When present, this overrides the normally determined execution platform.
     */
    public Builder setExecutionPlatformLabel(@Nullable Label executionPlatformLabel) {
      this.executionPlatformLabel = executionPlatformLabel;
      return this;
    }

    /** Builds a new {@link ConfiguredTargetKey} based on the supplied data. */
    public ConfiguredTargetKey build() {
      if (this.executionPlatformLabel != null) {
        return ToolchainDependencyConfiguredTargetKey.create(
            label, configurationKey, executionPlatformLabel);
      }
      return create(label, configurationKey);
    }
  }
}
