package org.checkerframework.dataflow.expression;

import java.math.BigInteger;
import java.util.Objects;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.Store;
import org.checkerframework.dataflow.cfg.node.ValueLiteralNode;
import org.checkerframework.javacutil.AnnotationProvider;
import org.checkerframework.javacutil.TypesUtils;

/** JavaExpression for literals. */
public class ValueLiteral extends JavaExpression {

  /** The value of the literal. */
  protected final @Nullable Object value;

  /** The negative of Long.MIN_VALUE, which does not fit in a long. */
  private final BigInteger NEGATIVE_LONG_MIN_VALUE = new BigInteger("9223372036854775808");

  /**
   * Creates a ValueLiteral from the node with the given type.
   *
   * @param type type of the literal
   * @param node the literal represents by this {@link
   *     org.checkerframework.dataflow.expression.ValueLiteral}
   */
  public ValueLiteral(TypeMirror type, ValueLiteralNode node) {
    super(type);
    value = node.getValue();
  }

  /**
   * Creates a ValueLiteral where the value is {@code value} that has the given type.
   *
   * @param type type of the literal
   * @param value the literal value
   */
  public ValueLiteral(TypeMirror type, Object value) {
    super(type);
    this.value = value;
  }

  /**
   * Returns the negation of this literal. Throws an exception if negation is not possible.
   *
   * @return the negation of this literal
   */
  public ValueLiteral negate() {
    if (TypesUtils.isIntegralPrimitive(type)) {
      if (value == null) {
        throw new Error("null value of integral type " + type);
      }
      return new ValueLiteral(type, negateBoxedPrimitive(value));
    }
    throw new Error(String.format("cannot negate: %s type=%s", this, type));
  }

  /**
   * Negate a boxed primitive.
   *
   * @param o a boxed primitive
   * @return a boxed primitive that is the negation of the argument
   */
  private Object negateBoxedPrimitive(Object o) {
    if (value instanceof Byte) {
      return (byte) -(Byte) value;
    }
    if (value instanceof Short) {
      return (short) -(Short) value;
    }
    if (value instanceof Integer) {
      return -(Integer) value;
    }
    if (value instanceof Long) {
      return -(Long) value;
    }
    if (value instanceof Float) {
      return -(Float) value;
    }
    if (value instanceof Double) {
      return -(Double) value;
    }
    if (value instanceof BigInteger) {
      assert value.equals(NEGATIVE_LONG_MIN_VALUE);
      return Long.MIN_VALUE;
    }
    throw new Error("Cannot be negated: " + o + " " + o.getClass());
  }

  /**
   * Returns the value of this literal.
   *
   * @return the value of this literal
   */
  public @Nullable Object getValue() {
    return value;
  }

  @Override
  public boolean containsOfClass(Class<? extends JavaExpression> clazz) {
    return getClass() == clazz;
  }

  @Override
  public boolean isDeterministic(AnnotationProvider provider) {
    return true;
  }

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

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

  @Override
  public boolean syntacticEquals(JavaExpression je) {
    return this.equals(je);
  }

  @Override
  public boolean containsSyntacticEqualJavaExpression(JavaExpression other) {
    return this.syntacticEquals(other);
  }

  @Override
  public boolean containsModifiableAliasOf(Store<?> store, JavaExpression other) {
    return false; // not modifiable
  }

  /// java.lang.Object methods

  @Override
  public boolean equals(@Nullable Object obj) {
    if (!(obj instanceof ValueLiteral)) {
      return false;
    }
    ValueLiteral other = (ValueLiteral) obj;
    // TODO:  Can this string comparison be cleaned up?
    // Cannot use Types.isSameType(type, other.type) because we don't have a Types object.
    return type.toString().equals(other.type.toString()) && Objects.equals(value, other.value);
  }

  @Override
  public String toString() {
    if (TypesUtils.isString(type)) {
      return "\"" + value + "\"";
    } else if (type.getKind() == TypeKind.LONG) {
      assert value != null : "@AssumeAssertion(nullness): invariant";
      return value.toString() + "L";
    } else if (type.getKind() == TypeKind.CHAR) {
      return "\'" + value + "\'";
    }
    return value == null ? "null" : value.toString();
  }

  @Override
  public int hashCode() {
    return Objects.hash(value, type.toString());
  }

  @Override
  public <R, P> R accept(JavaExpressionVisitor<R, P> visitor, P p) {
    return visitor.visitValueLiteral(this, p);
  }
}
