package org.checkerframework.dataflow.cfg.node;

import com.sun.source.tree.Tree;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicLong;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.builder.CFGBuilder;
import org.checkerframework.dataflow.qual.Pure;
import org.plumelib.util.UniqueId;

/**
 * A node in the abstract representation used for Java code inside a basic block.
 *
 * <p>The following invariants hold:
 *
 * <pre>
 * block == null || block instanceof RegularBlock || block instanceof ExceptionBlock
 * block != null &hArr; block.getNodes().contains(this)
 * </pre>
 *
 * <pre>
 * type != null
 * tree != null &rArr; node.getType() == InternalUtils.typeOf(node.getTree())
 * </pre>
 *
 * Note that two {@code Node}s can be {@code .equals} but represent different CFG nodes. Take care
 * to use reference equality, maps that handle identity {@code IdentityHashMap}, and sets like
 * {@code IdentityMostlySingleton}.
 *
 * @see org.checkerframework.dataflow.util.IdentityMostlySingleton
 */
public abstract class Node implements UniqueId {

  /**
   * The basic block this node belongs to. If null, this object represents a method formal
   * parameter.
   */
  protected @Nullable Block block;

  /** Is this node an l-value? */
  protected boolean lvalue = false;

  /** The assignment context of this node. See {@link AssignmentContext}. */
  protected @Nullable AssignmentContext assignmentContext;

  /**
   * Does this node represent a tree that appears in the source code (true) or one that the CFG
   * builder added while desugaring (false).
   */
  protected boolean inSource = true;

  /**
   * The type of this node. For {@link Node}s with {@link Tree}s, this type is the type of the
   * {@link Tree}. Otherwise, it is the type is set by the {@link CFGBuilder}.
   */
  protected final TypeMirror type;

  /** The unique ID for the next-created object. */
  static final AtomicLong nextUid = new AtomicLong(0);
  /** The unique ID of this object. */
  final long uid = nextUid.getAndIncrement();
  /**
   * Returns the unique ID of this object.
   *
   * @return the unique ID of this object
   */
  @Override
  public long getUid(@UnknownInitialization Node this) {
    return uid;
  }

  /**
   * Creates a new Node.
   *
   * @param type the type of the node
   */
  protected Node(TypeMirror type) {
    assert type != null;
    this.type = type;
  }

  /**
   * Returns the basic block this node belongs to (or {@code null} if it represents the parameter of
   * a method).
   *
   * @return the basic block this node belongs to (or {@code null} if it represents the parameter of
   *     a method)
   */
  public @Nullable Block getBlock() {
    return block;
  }

  /** Set the basic block this node belongs to. */
  public void setBlock(Block b) {
    block = b;
  }

  /**
   * Returns the {@link Tree} in the abstract syntax tree, or {@code null} if no corresponding tree
   * exists. For instance, this is the case for an {@link ImplicitThisNode}.
   *
   * @return the corresponding {@link Tree} or {@code null}
   */
  @Pure
  public abstract @Nullable Tree getTree();

  /**
   * Returns a {@link TypeMirror} representing the type of a {@link Node}. A {@link Node} will
   * always have a type even when it has no {@link Tree}.
   *
   * @return a {@link TypeMirror} representing the type of this {@link Node}
   */
  public TypeMirror getType() {
    return type;
  }

  /**
   * Accept method of the visitor pattern.
   *
   * @param <R> result type of the operation
   * @param <P> parameter type
   * @param visitor the visitor to be applied to this node
   * @param p the parameter for this operation
   */
  public abstract <R, P> R accept(NodeVisitor<R, P> visitor, P p);

  /** Is the node an lvalue or not? */
  @Pure
  public boolean isLValue() {
    return lvalue;
  }

  /** Make this node an l-value. */
  public void setLValue() {
    lvalue = true;
  }

  public boolean getInSource() {
    return inSource;
  }

  public void setInSource(boolean inSrc) {
    inSource = inSrc;
  }

  /** The assignment context for the node. */
  public @Nullable AssignmentContext getAssignmentContext() {
    return assignmentContext;
  }

  public void setAssignmentContext(AssignmentContext assignmentContext) {
    this.assignmentContext = assignmentContext;
  }

  /**
   * Returns a collection containing all of the operand {@link Node}s of this {@link Node}.
   *
   * @return a collection containing all of the operand {@link Node}s of this {@link Node}
   */
  public abstract Collection<Node> getOperands();

  /**
   * Returns a collection containing all of the operand {@link Node}s of this {@link Node}, as well
   * as (transitively) the operands of its operands.
   *
   * @return a collection containing all of the operand {@link Node}s of this {@link Node}, as well
   *     as (transitively) the operands of its operands
   */
  public Collection<Node> getTransitiveOperands() {
    ArrayDeque<Node> operands = new ArrayDeque<>(getOperands());
    ArrayDeque<Node> transitiveOperands = new ArrayDeque<>(operands.size());
    while (!operands.isEmpty()) {
      Node next = operands.removeFirst();
      operands.addAll(next.getOperands());
      transitiveOperands.add(next);
    }
    return transitiveOperands;
  }

  /**
   * Returns a verbose string representation of this, useful for debugging.
   *
   * @return a printed representation of this
   */
  public String toStringDebug() {
    return String.format("%s [%s]", this, this.getClassAndUid());
  }

  /**
   * Returns a verbose string representation of a collection of nodes, useful for debugging..
   *
   * @param nodes a collection of nodes to format
   * @return a printed representation of the given collection
   */
  public static String nodeCollectionToString(Collection<? extends Node> nodes) {
    StringJoiner result = new StringJoiner(", ", "[", "]");
    for (Node n : nodes) {
      result.add(n.toStringDebug());
    }
    return result.toString();
  }
}
