// 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.Unimplemented;
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.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 com.android.tools.r8.utils.BooleanUtils;
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 final DynamicTypeAssumption dynamicTypeAssumption;
  private final NonNullAssumption nonNullAssumption;
  private final Instruction origin;

  private Assume(
      DynamicTypeAssumption dynamicTypeAssumption,
      NonNullAssumption nonNullAssumption,
      Value dest,
      Value src,
      Instruction origin,
      AppView<?> appView) {
    super(dest, src);
    assert dynamicTypeAssumption != null || nonNullAssumption != null;
    assert BooleanUtils.intValue(dynamicTypeAssumption != null)
            + BooleanUtils.intValue(nonNullAssumption != null)
        == 1;
    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 (isAssumeDynamicType()) {
      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() {
    if (isAssumeDynamicType()) {
      return "AssumeDynamicType";
    }
    if (isAssumeNonNull()) {
      return "AssumeNonNull";
    }
    throw new Unimplemented();
  }

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

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

  @Override
  public boolean isAssumeDynamicType() {
    return dynamicTypeAssumption != null;
  }

  @Override
  public boolean isAssumeNonNull() {
    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 (isAssumeDynamicType()) {
      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 (isAssumeDynamicType()) {
      return src().getType();
    }
    if (isAssumeNonNull()) {
      assert src().getType().isReferenceType();
      return src().getType().asReferenceType().asMeetWithNotNull();
    }
    throw new Unimplemented();
  }

  @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) {
    assert super.verifyTypes(appView);

    TypeElement inType = src().getType();
    TypeElement outType = getOutType();
    if (isAssumeDynamicType()) {
      assert inType.isReferenceType() : inType;
      assert outType.equals(inType)
          : "At " + this + System.lineSeparator() + outType + " != " + inType;
    } else {
      assert isAssumeNonNull() : this;
      assert inType.isReferenceType() : inType;
      assert inType.isNullType() || outType.equals(inType.asReferenceType().asMeetWithNotNull())
          : "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.
    String originString =
        origin.hasBlock() ? " (origin: `" + origin.toString() + "`)" : " (obsolete origin)";
    if (isAssumeNonNull()) {
      return super.toString() + originString;
    }
    if (isAssumeDynamicType()) {
      return super.toString()
          + "; upper bound: "
          + dynamicTypeAssumption.dynamicUpperBoundType
          + (dynamicTypeAssumption.dynamicLowerBoundType != null
              ? "; lower bound: " + dynamicTypeAssumption.dynamicLowerBoundType
              : "")
          + originString;
    }
    return super.toString();
  }

  public static class DynamicTypeAssumption {

    private final TypeElement dynamicUpperBoundType;
    private final ClassTypeElement dynamicLowerBoundType;

    private 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;
    }
  }
}
