package org.checkerframework.dataflow.expression;

import com.sun.source.tree.Tree;
import java.util.Objects;
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.UnaryOperationNode;
import org.checkerframework.javacutil.AnnotationProvider;

/** JavaExpression for unary operations. */
public class UnaryOperation extends JavaExpression {

  /** The unary operation kind. */
  protected final Tree.Kind operationKind;
  /** The operand. */
  protected final JavaExpression operand;

  /**
   * Create a unary operation.
   *
   * @param type the type of the result
   * @param operationKind the operator
   * @param operand the operand
   */
  public UnaryOperation(TypeMirror type, Tree.Kind operationKind, JavaExpression operand) {
    super(operand.type);
    this.operationKind = operationKind;
    this.operand = operand;
  }

  /**
   * Create a unary operation.
   *
   * @param node the unary operation node
   * @param operand the operand
   */
  public UnaryOperation(UnaryOperationNode node, JavaExpression operand) {
    this(node.getType(), node.getTree().getKind(), operand);
  }

  /**
   * Returns the operator of this unary operation.
   *
   * @return the unary operation kind
   */
  public Tree.Kind getOperationKind() {
    return operationKind;
  }

  /**
   * Returns the operand of this unary operation.
   *
   * @return the operand
   */
  public JavaExpression getOperand() {
    return operand;
  }

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

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

  @Override
  public boolean isUnassignableByOtherCode() {
    return operand.isUnassignableByOtherCode();
  }

  @Override
  public boolean isUnmodifiableByOtherCode() {
    return operand.isUnmodifiableByOtherCode();
  }

  @Override
  public boolean syntacticEquals(JavaExpression je) {
    if (!(je instanceof UnaryOperation)) {
      return false;
    }
    UnaryOperation other = (UnaryOperation) je;
    return operationKind == other.getOperationKind() && operand.syntacticEquals(other.operand);
  }

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

  @Override
  public boolean containsModifiableAliasOf(Store<?> store, JavaExpression other) {
    return operand.containsModifiableAliasOf(store, other);
  }

  @Override
  public int hashCode() {
    return Objects.hash(operationKind, operand);
  }

  @Override
  public boolean equals(@Nullable Object other) {
    if (!(other instanceof UnaryOperation)) {
      return false;
    }
    UnaryOperation unOp = (UnaryOperation) other;
    return operationKind == unOp.getOperationKind() && operand.equals(unOp.operand);
  }

  @Override
  public String toString() {
    String operandString = operand.toString();
    switch (operationKind) {
      case BITWISE_COMPLEMENT:
        return "~" + operandString;
      case LOGICAL_COMPLEMENT:
        return "!" + operandString;
      case POSTFIX_DECREMENT:
        return operandString + "--";
      case POSTFIX_INCREMENT:
        return operandString + "++";
      case PREFIX_DECREMENT:
        return "--" + operandString;
      case PREFIX_INCREMENT:
        return "++" + operandString;
      case UNARY_MINUS:
        return "-" + operandString;
      case UNARY_PLUS:
        return "+" + operandString;
      default:
        throw new Error("Unrecognized unary operation kind " + operationKind);
    }
  }

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