// 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.BuildConfiguration;
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 BuildConfiguration}) pair used to trigger immediate
 * dependency resolution and the rule analysis.
 *
 * <p>In practice, a ({@link Label}, canonical and post-transition {@link
 * BuildConfigurationValue.Key}) 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 BuildConfigurationValue.Key} 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 BuildConfiguration} (due
 * to the skipped transitions).
 *
 * <p>2. The {@link BuildConfigurationValue.Key} must be canonical. Multiple keys can correspond to
 * the same {@link BuildConfiguration}. The canonical key is the one returned by {@link
 * BuildConfigurationValue.key}. Failure to use a canonical key can result in build graphs with
 * multiple seemingly-identical ConfiguredTarget that have the same ({@link Label}, {@link
 * BuildConfiguration}) pair. This is non-performant in all cases and incorrect if those
 * duplications lead to action conflicts due to unsharable actions.
 *
 * <p>3. A build should not request keys with equal ({@link Label}, {@link BuildConfiguration})
 * 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 BuildConfiguration}) pair.
 *
 * <p>Note that this key may be used to look up the generating action of an artifact.
 */
@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 BuildConfigurationValue.Key configurationKey;

  private final transient int hashCode;

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

  @AutoCodec.VisibleForSerialization
  @AutoCodec.Instantiator
  static ConfiguredTargetKey create(
      Label label, @Nullable BuildConfigurationValue.Key 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 BuildConfigurationValue.Key getConfigurationKey() {
    return configurationKey;
  }

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

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

  private static int computeHashCode(
      Label label,
      @Nullable BuildConfigurationValue.Key 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 BuildConfigurationValue.Key configurationKey,
        int hashCode,
        Label executionPlatformLabel) {
      super(label, configurationKey, hashCode);
      this.executionPlatformLabel = checkNotNull(executionPlatformLabel);
    }

    @AutoCodec.VisibleForSerialization
    @AutoCodec.Instantiator
    static ToolchainDependencyConfiguredTargetKey create(
        Label label,
        @Nullable BuildConfigurationValue.Key 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 BuildConfigurationValue.Key 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 BuildConfiguration} for the configured target. */
    public Builder setConfiguration(@Nullable BuildConfiguration buildConfiguration) {
      if (buildConfiguration == null) {
        return setConfigurationKey(null);
      } else {
        return setConfigurationKey(BuildConfigurationValue.key(buildConfiguration));
      }
    }

    /** Sets the configuration key for the configured target. */
    public Builder setConfigurationKey(@Nullable BuildConfigurationValue.Key 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);
    }
  }
}
