// Copyright (c) 2016, 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.code.CfCmp;
import com.android.tools.r8.code.CmpLong;
import com.android.tools.r8.code.CmpgDouble;
import com.android.tools.r8.code.CmpgFloat;
import com.android.tools.r8.code.CmplDouble;
import com.android.tools.r8.code.CmplFloat;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.analysis.constant.Bottom;
import com.android.tools.r8.ir.analysis.constant.ConstLatticeElement;
import com.android.tools.r8.ir.analysis.constant.LatticeElement;
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.utils.LongInterval;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import java.util.function.Function;

public class Cmp extends Binop {

  public enum Bias {
    NONE, GT, LT
  }

  private final Bias bias;

  public Cmp(NumericType type, Bias bias, Value dest, Value left, Value right) {
    super(type, dest, left, right);
    this.bias = bias;
  }

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

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

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

  @Override
  public void buildDex(DexBuilder builder) {
    com.android.tools.r8.code.Instruction instruction;
    int dest = builder.allocatedRegister(outValue, getNumber());
    int left = builder.allocatedRegister(leftValue(), getNumber());
    int right = builder.allocatedRegister(rightValue(), getNumber());
    switch (type) {
      case DOUBLE:
        assert bias != Bias.NONE;
        if (bias == Bias.GT) {
          instruction = new CmpgDouble(dest, left, right);
        } else {
          assert bias == Bias.LT;
          instruction = new CmplDouble(dest, left, right);
        }
        break;
      case FLOAT:
        assert bias != Bias.NONE;
        if (bias == Bias.GT) {
          instruction = new CmpgFloat(dest, left, right);
        } else {
          assert bias == Bias.LT;
          instruction = new CmplFloat(dest, left, right);
        }
        break;
      case LONG:
        assert bias == Bias.NONE;
        instruction = new CmpLong(dest, left, right);
        break;
      default:
        throw new Unreachable("Unexpected type " + type);
    }
    builder.add(this, instruction);
  }

  private String biasToString(Bias bias) {
    switch (bias) {
      case NONE:
        return "none";
      case GT:
        return "gt";
      case LT:
        return "lt";
      default:
        throw new Unreachable("Unexpected bias " + bias);
    }
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append(getClass().getSimpleName());
    builder.append(" (");
    switch (type) {
      case DOUBLE:
        builder.append("double, ");
        builder.append(biasToString(bias));
        break;
      case FLOAT:
        builder.append("float, ");
        builder.append(biasToString(bias));
        break;
      case LONG:
        builder.append("long");
        break;
      default:
        throw new Unreachable("Unexpected type " + type);
    }
    builder.append(")");
    for (int i = builder.length(); i < 20; i++) {
      builder.append(" ");
    }
    if (outValue != null) {
      builder.append(outValue);
      builder.append(" <- ");
    }
    StringUtils.append(builder, inValues, ", ", BraceType.NONE);
    return builder.toString();
  }

  @Override
  public boolean identicalNonValueNonPositionParts(Instruction other) {
    return other.isCmp() && other.asCmp().bias == bias;
  }

  @Override
  public int maxInValueRegister() {
    return Constants.U8BIT_MAX;
  }

  @Override
  public int maxOutValueRegister() {
    return Constants.U8BIT_MAX;
  }

  private boolean nonOverlapingRanges() {
    return type == NumericType.LONG
        && leftValue().hasValueRange()
        && rightValue().hasValueRange()
        && leftValue().getValueRange().doesntOverlapWith(rightValue().getValueRange());
  }

  @Override
  public boolean canBeFolded() {
    return (leftValue().isConstNumber() && rightValue().isConstNumber()) || nonOverlapingRanges();
  }

  @Override
  public LatticeElement evaluate(IRCode code, Function<Value, LatticeElement> getLatticeElement) {
    LatticeElement leftLattice = getLatticeElement.apply(leftValue());
    LatticeElement rightLattice = getLatticeElement.apply(rightValue());
    if (leftLattice.isConst() && rightLattice.isConst()) {
      ConstNumber leftConst = leftLattice.asConst().getConstNumber();
      ConstNumber rightConst = rightLattice.asConst().getConstNumber();
      int result;
      if (type == NumericType.LONG) {
        result = Integer.signum(Long.compare(leftConst.getLongValue(), rightConst.getLongValue()));
      } else if (type == NumericType.FLOAT) {
        float left = leftConst.getFloatValue();
        float right = rightConst.getFloatValue();
        if (Float.isNaN(left) || Float.isNaN(right)) {
          result = bias == Bias.GT ? 1 : -1;
        } else {
          result = (int) Math.signum(left - right);
        }
      } else {
        assert type == NumericType.DOUBLE;
        double left = leftConst.getDoubleValue();
        double right = rightConst.getDoubleValue();
        if (Double.isNaN(left) || Double.isNaN(right)) {
          result = bias == Bias.GT ? 1 : -1;
        } else {
          result = (int) Math.signum(left - right);
        }
      }
      Value value = code.createValue(TypeElement.getInt(), getLocalInfo());
      ConstNumber newConst = new ConstNumber(value, result);
      return new ConstLatticeElement(newConst);
    } else if (leftLattice.isValueRange() && rightLattice.isConst()) {
      Value leftValueRange = leftLattice.asConstRange().getConstRange();
      ConstNumber rightConst = rightLattice.asConst().getConstNumber();
      return buildLatticeResult(code, leftValueRange.getValueRange(),
          rightConst.outValue().getValueRange());
    } else if (leftLattice.isConst() && rightLattice.isValueRange()) {
      Value rigthValueRange = rightLattice.asConstRange().getConstRange();
      ConstNumber leftConst = leftLattice.asConst().getConstNumber();
      return buildLatticeResult(code, leftConst.outValue().getValueRange(),
          rigthValueRange.getValueRange());
    } else if (leftLattice.isValueRange() && rightLattice.isValueRange()) {
      Value rigthValueRange = rightLattice.asConstRange().getConstRange();
      Value leftValueRange = leftLattice.asConstRange().getConstRange();
      return buildLatticeResult(code, leftValueRange.getValueRange(),
          rigthValueRange.getValueRange());
    }
    return Bottom.getInstance();
  }

  private LatticeElement buildLatticeResult(IRCode code, LongInterval leftRange,
      LongInterval rightRange) {
    if (leftRange.overlapsWith(rightRange)) {
      return Bottom.getInstance();
    }
    int result = Integer.signum(Long.compare(leftRange.getMin(), rightRange.getMin()));
    Value value = code.createValue(TypeElement.getInt(), getLocalInfo());
    ConstNumber newConst = new ConstNumber(value, result);
    return new ConstLatticeElement(newConst);
  }

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

  @Override
  public Cmp asCmp() {
    return this;
  }

  @Override
  public void buildCf(CfBuilder builder) {
    builder.add(new CfCmp(bias, type));
  }

  @Override
  public TypeElement evaluate(AppView<?> appView) {
    return TypeElement.getInt();
  }

}
