// Copyright (c) 2017, 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.ir.analysis.type;

import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;

import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import java.util.Objects;
import java.util.function.Function;

public class ArrayTypeLatticeElement extends ReferenceTypeLatticeElement {

  private final TypeLatticeElement memberTypeLattice;

  // On-demand link between other nullability-variants.
  private final NullabilityVariants<ArrayTypeLatticeElement> variants;

  public static ArrayTypeLatticeElement create(
      TypeLatticeElement memberTypeLattice, Nullability nullability) {
    return NullabilityVariants.create(
        nullability,
        (variants) -> new ArrayTypeLatticeElement(memberTypeLattice, nullability, variants));
  }

  private ArrayTypeLatticeElement(
      TypeLatticeElement memberTypeLattice,
      Nullability nullability,
      NullabilityVariants<ArrayTypeLatticeElement> variants) {
    super(nullability);
    assert memberTypeLattice.isPrimitive() || memberTypeLattice.nullability().isMaybeNull();
    this.memberTypeLattice = memberTypeLattice;
    this.variants = variants;
  }

  public DexType getArrayType(DexItemFactory factory) {
    TypeLatticeElement baseTypeLattice = getArrayBaseTypeLattice();
    DexType baseType;
    if (baseTypeLattice.isPrimitive()) {
      baseType = baseTypeLattice.asPrimitiveTypeLatticeElement().toDexType(factory);
    } else {
      assert baseTypeLattice.isClassType();
      baseType = baseTypeLattice.asClassTypeLatticeElement().getClassType();
    }
    return factory.createArrayType(getNesting(), baseType);
  }

  public int getNesting() {
    int nesting = 1;
    TypeLatticeElement member = getArrayMemberTypeAsMemberType();
    while (member.isArrayType()) {
      ++nesting;
      member = member.asArrayTypeLatticeElement().getArrayMemberTypeAsMemberType();
    }
    return nesting;
  }

  public TypeLatticeElement getArrayMemberTypeAsMemberType() {
    return memberTypeLattice;
  }

  public TypeLatticeElement getArrayMemberTypeAsValueType() {
    return memberTypeLattice.isFineGrainedType() ? getInt() : memberTypeLattice;
  }

  public TypeLatticeElement getArrayBaseTypeLattice() {
    TypeLatticeElement base = getArrayMemberTypeAsMemberType();
    while (base.isArrayType()) {
      base = base.asArrayTypeLatticeElement().getArrayMemberTypeAsMemberType();
    }
    return base;
  }

  private ArrayTypeLatticeElement createVariant(
      Nullability nullability, NullabilityVariants<ArrayTypeLatticeElement> variants) {
    assert this.nullability != nullability;
    return new ArrayTypeLatticeElement(memberTypeLattice, nullability, variants);
  }

  @Override
  public ReferenceTypeLatticeElement getOrCreateVariant(Nullability nullability) {
    ArrayTypeLatticeElement variant = variants.get(nullability);
    if (variant != null) {
      return variant;
    }
    return variants.getOrCreateElement(nullability, this::createVariant);
  }

  @Override
  public boolean isBasedOnMissingClass(AppView<? extends AppInfoWithSubtyping> appView) {
    return memberTypeLattice.isBasedOnMissingClass(appView);
  }

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

  @Override
  public ArrayTypeLatticeElement asArrayTypeLatticeElement() {
    return this;
  }

  @Override
  public String toString() {
    return nullability.toString() + " (" + memberTypeLattice.toString() + "[])";
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof ArrayTypeLatticeElement)) {
      return false;
    }
    ArrayTypeLatticeElement other = (ArrayTypeLatticeElement) o;
    if (nullability() != other.nullability()) {
      return false;
    }
    return memberTypeLattice.equals(other.memberTypeLattice);
  }

  @Override
  public int hashCode() {
    return Objects.hash(nullability, memberTypeLattice);
  }

  @Override
  public ArrayTypeLatticeElement fixupClassTypeReferences(
      Function<DexType, DexType> mapping, AppView<? extends AppInfoWithSubtyping> appView) {
    if (memberTypeLattice.isReference()) {
      TypeLatticeElement substitutedMemberType =
          memberTypeLattice.fixupClassTypeReferences(mapping, appView);
      if (substitutedMemberType != memberTypeLattice) {
        return ArrayTypeLatticeElement.create(substitutedMemberType, nullability);
      }
    }
    return this;
  }

  ReferenceTypeLatticeElement join(ArrayTypeLatticeElement other, AppView<?> appView) {
    Nullability nullability = nullability().join(other.nullability());
    ReferenceTypeLatticeElement join =
        joinMember(this.memberTypeLattice, other.memberTypeLattice, appView, nullability);
    if (join == null) {
      // Check if other has the right nullability before creating it.
      if (other.nullability == nullability) {
        return other;
      } else {
        return getOrCreateVariant(nullability);
      }
    } else {
      assert join.nullability == nullability;
      return join;
    }
  }

  private static ReferenceTypeLatticeElement joinMember(
      TypeLatticeElement aMember,
      TypeLatticeElement bMember,
      AppView<?> appView,
      Nullability nullability) {
    if (aMember.equals(bMember)) {
      // Return null indicating the join is the same as the member to avoid object allocation.
      return null;
    }
    if (aMember.isArrayType() && bMember.isArrayType()) {
      TypeLatticeElement join =
          joinMember(
              aMember.asArrayTypeLatticeElement().memberTypeLattice,
              bMember.asArrayTypeLatticeElement().memberTypeLattice,
              appView,
              maybeNull());
      return join == null ? null : ArrayTypeLatticeElement.create(join, nullability);
    }
    if (aMember.isClassType() && bMember.isClassType()) {
      ReferenceTypeLatticeElement join =
          aMember.asClassTypeLatticeElement().join(bMember.asClassTypeLatticeElement(), appView);
      return ArrayTypeLatticeElement.create(join, nullability);
    }
    if (aMember.isPrimitive() || bMember.isPrimitive()) {
      return objectClassType(appView, nullability);
    }
    return objectArrayType(appView, nullability);
  }
}
