// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.synthesis;

import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.structural.RepresentativeMap;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;

/**
 * Base type for the definition of a synthetic item.
 *
 * <p>This class is internal to the synthetic items collection, thus package-protected.
 */
abstract class SyntheticDefinition<
    R extends SyntheticReference<R, D, C>,
    D extends SyntheticDefinition<R, D, C>,
    C extends DexClass> {

  private final SyntheticKind kind;
  private final SynthesizingContext context;

  SyntheticDefinition(SyntheticKind kind, SynthesizingContext context) {
    assert kind != null;
    assert context != null;
    this.kind = kind;
    this.context = context;
  }

  public boolean isClasspathDefinition() {
    return false;
  }

  public SyntheticClasspathDefinition asClasspathDefinition() {
    return null;
  }

  public boolean isProgramDefinition() {
    return false;
  }

  public SyntheticProgramDefinition asProgramDefinition() {
    return null;
  }

  abstract R toReference();

  final SyntheticKind getKind() {
    return kind;
  }

  final SynthesizingContext getContext() {
    return context;
  }

  final String getPrefixForExternalSyntheticType() {
    return SyntheticNaming.getPrefixForExternalSyntheticType(getKind(), getHolder().getType());
  }

  public abstract C getHolder();

  final HashCode computeHash(
      RepresentativeMap map,
      boolean intermediate,
      ClassToFeatureSplitMap classToFeatureSplitMap,
      SyntheticItems syntheticItems) {
    Hasher hasher = Hashing.murmur3_128().newHasher();
    hasher.putInt(kind.id);
    if (getKind().isFixedSuffixSynthetic) {
      // Fixed synthetics are non-shareable. Its unique type is used as the hash key.
      getHolder().getType().hash(hasher);
      return hasher.hash();
    }
    if (intermediate) {
      // If in intermediate mode, include the context type as sharing is restricted to within a
      // single context.
      getContext().getSynthesizingContextType().hashWithTypeEquivalence(hasher, map);
    }
    hasher.putInt(context.getFeatureSplit().hashCode());
    internalComputeHash(hasher, map);
    return hasher.hash();
  }

  abstract void internalComputeHash(Hasher hasher, RepresentativeMap map);

  final boolean isEquivalentTo(
      D other,
      boolean includeContext,
      GraphLens graphLens,
      ClassToFeatureSplitMap classToFeatureSplitMap,
      SyntheticItems syntheticItems) {
    return compareTo(other, includeContext, graphLens, classToFeatureSplitMap, syntheticItems) == 0;
  }

  int compareTo(
      D other,
      boolean includeContext,
      GraphLens graphLens,
      ClassToFeatureSplitMap classToFeatureSplitMap,
      SyntheticItems syntheticItems) {
    {
      int order = kind.compareTo(other.getKind());
      if (order != 0) {
        return order;
      }
    }
    DexType thisType = getHolder().getType();
    DexType otherType = other.getHolder().getType();
    if (getKind().isFixedSuffixSynthetic) {
      // Fixed synthetics are non-shareable. Ordered by their unique type.
      return thisType.compareTo(otherType);
    }
    if (includeContext) {
      int order = getContext().compareTo(other.getContext());
      if (order != 0) {
        return order;
      }
    }
    if (getContext().getFeatureSplit() != other.getContext().getFeatureSplit()) {
      int order =
          classToFeatureSplitMap.compareFeatureSplits(
              context.getFeatureSplit(), other.getContext().getFeatureSplit());
      assert order != 0;
      return order;
    }
    RepresentativeMap map = null;
    // If the synthetics have been moved include the original types in the equivalence.
    if (graphLens.isNonIdentityLens()) {
      DexType thisOrigType = graphLens.getOriginalType(thisType);
      DexType otherOrigType = graphLens.getOriginalType(otherType);
      if (thisType != thisOrigType || otherType != otherOrigType) {
        map =
            t -> {
              if (t == otherType || t == thisOrigType || t == otherOrigType) {
                return thisType;
              }
              return t;
            };
      }
    }
    if (map == null) {
      map = t -> t == otherType ? thisType : t;
    }
    return internalCompareTo(other, map);
  }

  abstract int internalCompareTo(D other, RepresentativeMap map);

  public abstract boolean isValid();
}
