// Copyright 2018 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.common.collect.ImmutableSortedSet;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.util.Fingerprint;
import java.util.Arrays;
import javax.annotation.Nullable;

/**
 * A wrapper class for an {@code ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>>}
 * object. Interning these objects allows us to do cheap reference equality checks when these sets
 * are in frequently used keys. For good measure, we also compute a fingerprint.
 */
public class FragmentClassSet {
  private final ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> fragments;

  // Lazily initialized.
  @Nullable private volatile byte[] fingerprint;
  private volatile int hashCode;

  private FragmentClassSet(
      ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> fragments) {
    this.fragments = fragments;
  }

  private static final Interner<FragmentClassSet> interner = BlazeInterners.newWeakInterner();

  public static FragmentClassSet of(
      ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> fragments) {
    return interner.intern(new FragmentClassSet(fragments));
  }

  public ImmutableSortedSet<Class<? extends BuildConfiguration.Fragment>> fragmentClasses() {
    return fragments;
  }

  /**
   * Lazily initialize {@link #fingerprint} and {@link #hashCode}. Keeps computation off critical
   * path of build, while still avoiding expensive computation for equality and hash code each time.
   *
   * <p>We check for nullity of {@link #fingerprint} to see if this method has already been called.
   * Using {@link #hashCode} after this method is called is safe because it is set here before
   * {@link #fingerprint} is set, so if {@link #fingerprint} is non-null then {@link #hashCode} is
   * definitely set.
   */
  private void maybeInitializeFingerprintAndHashCode() {
    if (fingerprint != null) {
      return;
    }
    synchronized (this) {
      if (fingerprint != null) {
        return;
      }
      Fingerprint fingerprint = new Fingerprint();
      for (Class<? extends BuildConfiguration.Fragment> fragment : fragments) {
        fingerprint.addString(fragment.getName());
      }
      byte[] computedFingerprint = fingerprint.digestAndReset();
      hashCode = Arrays.hashCode(computedFingerprint);
      this.fingerprint = computedFingerprint;
    }
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    } else if (!(other instanceof FragmentClassSet)) {
      return false;
    } else {
      maybeInitializeFingerprintAndHashCode();
      FragmentClassSet that = (FragmentClassSet) other;
      that.maybeInitializeFingerprintAndHashCode();
      return Arrays.equals(this.fingerprint, that.fingerprint);
    }
  }

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