// Copyright (c) 2018, 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.code;

import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.VerifyTypesHelper;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import java.util.Objects;
import java.util.Set;

public class Assume extends Instruction {

  private static final String ERROR_MESSAGE =
      "Expected Assume instructions to be removed after IR processing.";

  private DynamicTypeAssumption dynamicTypeAssumption;
  private final NonNullAssumption nonNullAssumption;
  private final Instruction origin;

  public Assume(
      DynamicTypeAssumption dynamicTypeAssumption,
      NonNullAssumption nonNullAssumption,
      Value dest,
      Value src,
      Instruction origin,
      AppView<?> appView) {
    super(dest, src);
    assert dynamicTypeAssumption != null || nonNullAssumption != null;
    assert dynamicTypeAssumption == null
        || dynamicTypeAssumption.verifyCorrectnessOfValues(dest, src, appView);
    assert nonNullAssumption == null
        || nonNullAssumption.verifyCorrectnessOfValues(dest, src, appView);
    assert dest != null;
    this.dynamicTypeAssumption = dynamicTypeAssumption;
    this.nonNullAssumption = nonNullAssumption;
    this.origin = origin;
  }

  public static Assume createAssumeNonNullInstruction(
      Value dest, Value src, Instruction origin, AppView<?> appView) {
    return new Assume(null, NonNullAssumption.get(), dest, src, origin, appView);
  }

  public static Assume createAssumeDynamicTypeInstruction(
      TypeElement dynamicUpperBoundType,
      ClassTypeElement dynamicLowerBoundType,
      Value dest,
      Value src,
      Instruction origin,
      AppView<?> appView) {
    return new Assume(
        new DynamicTypeAssumption(dynamicUpperBoundType, dynamicLowerBoundType),
        null,
        dest,
        src,
        origin,
        appView);
  }

  @Override
  public int opcode() {
    return Opcodes.ASSUME;
  }

  public boolean verifyInstructionIsNeeded(AppView<?> appView) {
    if (hasDynamicTypeAssumption()) {
      assert dynamicTypeAssumption.verifyCorrectnessOfValues(outValue(), src(), appView);
    }
    return true;
  }

  @Override
  public <T> T accept(InstructionVisitor<T> visitor) {
    return visitor.visit(this);
  }

  public DynamicTypeAssumption getDynamicTypeAssumption() {
    return dynamicTypeAssumption;
  }

  public NonNullAssumption getNonNullAssumption() {
    return nonNullAssumption;
  }

  public Value src() {
    return inValues.get(0);
  }

  public Instruction origin() {
    return origin;
  }

  @Override
  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
    return src().knownToBeBoolean(seen);
  }

  @Override
  public String getInstructionName() {
    return "Assume";
  }

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

  @Override
  public Assume asAssume() {
    return this;
  }

  public boolean hasDynamicTypeAssumption() {
    return dynamicTypeAssumption != null;
  }

  public void unsetDynamicTypeAssumption() {
    dynamicTypeAssumption = null;
  }

  public boolean hasNonNullAssumption() {
    return nonNullAssumption != null;
  }

  @Override
  public boolean couldIntroduceAnAlias(AppView<?> appView, Value root) {
    assert root != null && root.getType().isReferenceType();
    assert outValue != null;
    TypeElement outType = outValue.getType();
    if (outType.isPrimitiveType()) {
      return false;
    }
    if (hasDynamicTypeAssumption()) {
      outType = dynamicTypeAssumption.getDynamicUpperBoundType();
    }
    if (appView.appInfo().hasLiveness()) {
      if (outType.isClassType()
          && root.getType().isClassType()
          && appView
              .appInfo()
              .withLiveness()
              .inDifferentHierarchy(
                  outType.asClassType().getClassType(),
                  root.getType().asClassType().getClassType())) {
        return false;
      }
    }
    return outType.isReferenceType();
  }

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

  @Override
  public Value getAliasForOutValue() {
    return src();
  }

  @Override
  public void buildDex(DexBuilder builder) {
    throw new Unreachable(ERROR_MESSAGE);
  }

  @Override
  public void buildCf(CfBuilder builder) {
    throw new Unreachable(ERROR_MESSAGE);
  }

  @Override
  public int maxInValueRegister() {
    throw new Unreachable(ERROR_MESSAGE);
  }

  @Override
  public int maxOutValueRegister() {
    throw new Unreachable(ERROR_MESSAGE);
  }

  @Override
  public boolean isOutConstant() {
    return false;
  }

  @Override
  public boolean identicalNonValueNonPositionParts(Instruction other) {
    if (!other.isAssume()) {
      return false;
    }
    Assume assumeInstruction = other.asAssume();
    return Objects.equals(dynamicTypeAssumption, assumeInstruction.dynamicTypeAssumption)
        && Objects.equals(nonNullAssumption, assumeInstruction.nonNullAssumption);
  }

  @Override
  public ConstraintWithTarget inliningConstraint(
      InliningConstraints inliningConstraints, ProgramMethod context) {
    return inliningConstraints.forAssume();
  }

  @Override
  public TypeElement evaluate(AppView<?> appView) {
    if (hasNonNullAssumption()) {
      assert src().getType().isReferenceType();
      return src().getType().asReferenceType().asMeetWithNotNull();
    }
    return src().getType();
  }

  @Override
  public DexType computeVerificationType(AppView<?> appView, TypeVerificationHelper helper) {
    return helper.getDexType(src());
  }

  @Override
  public boolean hasInvariantOutType() {
    return false;
  }

  @Override
  public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
    throw new Unreachable(ERROR_MESSAGE);
  }

  @Override
  public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
    return false;
  }

  @Override
  public boolean verifyTypes(AppView<?> appView, VerifyTypesHelper verifyTypesHelper) {
    assert super.verifyTypes(appView, verifyTypesHelper);

    TypeElement inType = src().getType();
    assert inType.isReferenceType() : inType;

    TypeElement outType = getOutType();
    if (hasNonNullAssumption()) {
      assert inType.isNullType() || outType.equals(inType.asReferenceType().asMeetWithNotNull())
          : "At " + this + System.lineSeparator() + outType + " != " + inType;
    } else {
      assert outType.equals(inType)
          : "At " + this + System.lineSeparator() + outType + " != " + inType;
    }
    return true;
  }

  @Override
  public String toString() {
    // `origin` could become obsolete:
    //   1) during branch simplification, the origin `if` could be simplified, which means the
    //     assumption became "truth."
    //   2) invoke-interface could be devirtualized, while its dynamic type and/or non-null receiver
    //     are still valid.
    StringBuilder builder = new StringBuilder(super.toString());
    if (hasNonNullAssumption()) {
      builder.append("; not null");
    }
    if (hasDynamicTypeAssumption()) {
      if (hasOutValue()) {
        if (!dynamicTypeAssumption.dynamicUpperBoundType.equalUpToNullability(outValue.getType())) {
          builder.append("; upper bound: ").append(dynamicTypeAssumption.dynamicUpperBoundType);
        }
      }
      if (dynamicTypeAssumption.dynamicLowerBoundType != null) {
        builder.append("; lower bound: ").append(dynamicTypeAssumption.dynamicLowerBoundType);
      }
    }
    return builder.toString();
  }

  public static class DynamicTypeAssumption {

    private final TypeElement dynamicUpperBoundType;
    private final ClassTypeElement dynamicLowerBoundType;

    public DynamicTypeAssumption(
        TypeElement dynamicUpperBoundType, ClassTypeElement dynamicLowerBoundType) {
      this.dynamicUpperBoundType = dynamicUpperBoundType;
      this.dynamicLowerBoundType = dynamicLowerBoundType;
    }

    public TypeElement getDynamicUpperBoundType() {
      return dynamicUpperBoundType;
    }

    public ClassTypeElement getDynamicLowerBoundType() {
      return dynamicLowerBoundType;
    }

    public boolean verifyCorrectnessOfValues(Value dest, Value src, AppView<?> appView) {
      assert dynamicUpperBoundType.lessThanOrEqualUpToNullability(src.getType(), appView);
      return true;
    }

    @Override
    public boolean equals(Object other) {
      if (other == null) {
        return false;
      }
      if (getClass() != other.getClass()) {
        return false;
      }
      DynamicTypeAssumption assumption = (DynamicTypeAssumption) other;
      return dynamicUpperBoundType == assumption.dynamicUpperBoundType
          && dynamicLowerBoundType == assumption.dynamicLowerBoundType;
    }

    @Override
    public int hashCode() {
      return Objects.hash(dynamicUpperBoundType, dynamicLowerBoundType);
    }
  }

  public static class NonNullAssumption {

    private static final NonNullAssumption instance = new NonNullAssumption();

    private NonNullAssumption() {}

    public static NonNullAssumption get() {
      return instance;
    }

    public boolean verifyCorrectnessOfValues(Value dest, Value src, AppView<?> appView) {
      assert !src.isNeverNull();
      return true;
    }
  }
}
