// 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 com.google.common.base.Preconditions;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey;
import com.google.devtools.build.lib.analysis.AliasProvider;
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;

/**
 * A (Label, Configuration key) pair. Note that this pair may be used to look up the generating
 * action of an artifact.
 */
@AutoCodec
public class ConfiguredTargetKey extends ActionLookupKey {
  private final Label label;
  @Nullable private final BuildConfigurationValue.Key configurationKey;

  private transient int hashCode;

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

  private static Label getLabel(ConfiguredTarget configuredTarget) {
    AliasProvider aliasProvider = configuredTarget.getProvider(AliasProvider.class);
    return aliasProvider != null
        ? aliasProvider.getAliasChain().get(0)
        : configuredTarget.getLabel();
  }

  public static ConfiguredTargetKey of(
      ConfiguredTarget configuredTarget, BuildConfiguration buildConfiguration) {
    return of(getLabel(configuredTarget), buildConfiguration);
  }

  public static ConfiguredTargetKey of(
      ConfiguredTarget configuredTarget,
      BuildConfigurationValue.Key configurationKey,
      boolean isHostConfiguration) {
    return of(getLabel(configuredTarget), configurationKey, isHostConfiguration);
  }

  public static ConfiguredTargetKey inTargetConfig(ConfiguredTarget configuredTarget) {
    return of(
        getLabel(configuredTarget),
        configuredTarget.getConfigurationKey(),
        /*isHostConfiguration=*/ false);
  }

  /**
   * Caches 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 static final Interner<HostConfiguredTargetKey> hostInterner =
      BlazeInterners.newWeakInterner();

  public static ConfiguredTargetKey of(Label label, @Nullable BuildConfiguration configuration) {
    KeyAndHost keyAndHost = keyFromConfiguration(configuration);
    return of(label, keyAndHost.key, keyAndHost.isHost);
  }

  @AutoCodec.Instantiator
  public static ConfiguredTargetKey of(
      Label label,
      @Nullable BuildConfigurationValue.Key configurationKey,
      boolean isHostConfiguration) {
    if (isHostConfiguration) {
      return hostInterner.intern(new HostConfiguredTargetKey(label, configurationKey));
    } else {
      return interner.intern(new ConfiguredTargetKey(label, configurationKey));
    }
  }

  static KeyAndHost keyFromConfiguration(@Nullable BuildConfiguration configuration) {
    return configuration == null
        ? KeyAndHost.NULL_INSTANCE
        : new KeyAndHost(
            BuildConfigurationValue.key(configuration), configuration.isHostConfiguration());
  }

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

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

  @Nullable
  BuildConfigurationValue.Key getConfigurationKey() {
    return configurationKey;
  }

  @Override
  public int hashCode() {
    // We use the hash code caching strategy employed by java.lang.String. There are three subtle
    // things going on here:
    //
    // (1) We use a value of 0 to indicate that the hash code hasn't been computed and cached yet.
    // Yes, this means that if the hash code is really 0 then we will "recompute" it each time. But
    // this isn't a problem in practice since a hash code of 0 should be rare.
    //
    // (2) Since we have no synchronization, multiple threads can race here thinking there are the
    // first one to compute and cache the hash code.
    //
    // (3) Moreover, since 'hashCode' is non-volatile, the cached hash code value written from one
    // thread may not be visible by another.
    //
    // All three of these issues are benign from a correctness perspective; in the end we have no
    // overhead from synchronization, at the cost of potentially computing the hash code more than
    // once.
    int h = hashCode;
    if (h == 0) {
      h = computeHashCode();
      hashCode = h;
    }
    return h;
  }

  private int computeHashCode() {
    int configVal = configurationKey == null ? 79 : configurationKey.hashCode();
    return 31 * label.hashCode() + configVal + (isHostConfiguration() ? 41 : 0);
  }

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

  public boolean isHostConfiguration() {
    return false;
  }

  public String prettyPrint() {
    if (label == null) {
      return "null";
    }
    return isHostConfiguration() ? (label + " (host)") : label.toString();
  }

  @Override
  public String toString() {
    return String.format("%s %s %s", label, configurationKey, isHostConfiguration());
  }

  static class HostConfiguredTargetKey extends ConfiguredTargetKey {
    private HostConfiguredTargetKey(
        Label label, @Nullable BuildConfigurationValue.Key configurationKey) {
      super(label, configurationKey);
    }

    @Override
    public boolean isHostConfiguration() {
      return true;
    }
  }

  /**
   * Simple wrapper class for turning a {@link BuildConfiguration} into a {@link
   * BuildConfigurationValue.Key} and boolean isHost.
   */
  public static class KeyAndHost {
    private static final KeyAndHost NULL_INSTANCE = new KeyAndHost(null, false);

    @Nullable public final BuildConfigurationValue.Key key;
    final boolean isHost;

    private KeyAndHost(@Nullable BuildConfigurationValue.Key key, boolean isHost) {
      this.key = key;
      this.isHost = isHost;
    }
  }
}
