package org.checkerframework.dataflow.cfg.builder;

import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.TreePath;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.dataflow.cfg.ControlFlowGraph;
import org.checkerframework.dataflow.cfg.UnderlyingAST;
import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.block.ConditionalBlockImpl;
import org.checkerframework.dataflow.cfg.block.ExceptionBlockImpl;
import org.checkerframework.dataflow.cfg.block.SingleSuccessorBlockImpl;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.javacutil.AnnotationProvider;
import org.checkerframework.javacutil.BasicAnnotationProvider;
import org.checkerframework.javacutil.trees.TreeBuilder;

/**
 * Builds the control flow graph of some Java code (either a method, or an arbitrary statement).
 *
 * <p>The translation of the AST to the CFG is split into three phases:
 *
 * <ol>
 *   <li><em>Phase one.</em> In the first phase, the AST is translated into a sequence of {@link
 *       org.checkerframework.dataflow.cfg.builder.ExtendedNode}s. An extended node can either be a
 *       {@link Node}, or one of several meta elements such as a conditional or unconditional jump
 *       or a node with additional information about exceptions. Some of the extended nodes contain
 *       labels (e.g., for the jump target), and phase one additionally creates a mapping from
 *       labels to extended nodes. Finally, the list of leaders is computed: A leader is an extended
 *       node which will give rise to a basic block in phase two.
 *   <li><em>Phase two.</em> In this phase, the sequence of extended nodes is translated to a graph
 *       of control flow blocks that contain nodes. The meta elements from phase one are translated
 *       into the correct edges.
 *   <li><em>Phase three.</em> The control flow graph generated in phase two can contain degenerate
 *       basic blocks such as empty regular basic blocks or conditional basic blocks that have the
 *       same block as both 'then' and 'else' successor. This phase removes these cases while
 *       preserving the control flow structure.
 * </ol>
 */
public abstract class CFGBuilder {

  /**
   * Build the control flow graph of some code.
   *
   * @param root the compilation unit
   * @param underlyingAST the AST that underlies the control frow graph
   * @param assumeAssertionsDisabled can assertions be assumed to be disabled?
   * @param assumeAssertionsEnabled can assertions be assumed to be enabled?
   * @param env annotation processing environment containing type utilities
   * @return a control flow graph
   */
  public static ControlFlowGraph build(
      CompilationUnitTree root,
      UnderlyingAST underlyingAST,
      boolean assumeAssertionsEnabled,
      boolean assumeAssertionsDisabled,
      ProcessingEnvironment env) {
    TreeBuilder builder = new TreeBuilder(env);
    AnnotationProvider annotationProvider = new BasicAnnotationProvider();
    PhaseOneResult phase1result =
        new CFGTranslationPhaseOne(
                builder, annotationProvider, assumeAssertionsEnabled, assumeAssertionsDisabled, env)
            .process(root, underlyingAST);
    ControlFlowGraph phase2result = CFGTranslationPhaseTwo.process(phase1result);
    ControlFlowGraph phase3result = CFGTranslationPhaseThree.process(phase2result);
    return phase3result;
  }

  /**
   * Build the control flow graph of some code (method, initializer block, ...). bodyPath is the
   * TreePath to the body of that code.
   */
  public static ControlFlowGraph build(
      TreePath bodyPath,
      UnderlyingAST underlyingAST,
      boolean assumeAssertionsEnabled,
      boolean assumeAssertionsDisabled,
      ProcessingEnvironment env) {
    TreeBuilder builder = new TreeBuilder(env);
    AnnotationProvider annotationProvider = new BasicAnnotationProvider();
    PhaseOneResult phase1result =
        new CFGTranslationPhaseOne(
                builder, annotationProvider, assumeAssertionsEnabled, assumeAssertionsDisabled, env)
            .process(bodyPath, underlyingAST);
    ControlFlowGraph phase2result = CFGTranslationPhaseTwo.process(phase1result);
    ControlFlowGraph phase3result = CFGTranslationPhaseThree.process(phase2result);
    return phase3result;
  }

  /** Build the control flow graph of some code. */
  public static ControlFlowGraph build(
      CompilationUnitTree root, UnderlyingAST underlyingAST, ProcessingEnvironment env) {
    return build(root, underlyingAST, false, false, env);
  }

  /** Build the control flow graph of a method. */
  public static ControlFlowGraph build(
      CompilationUnitTree root, MethodTree tree, ClassTree classTree, ProcessingEnvironment env) {
    UnderlyingAST underlyingAST = new CFGMethod(tree, classTree);
    return build(root, underlyingAST, false, false, env);
  }

  /**
   * Return a printed representation of a collection of extended nodes.
   *
   * @param nodes a collection of extended nodes to format
   * @return a printed representation of the given collection
   */
  public static String extendedNodeCollectionToStringDebug(
      Collection<? extends ExtendedNode> nodes) {
    StringJoiner result = new StringJoiner(", ", "[", "]");
    for (ExtendedNode n : nodes) {
      result.add(n.toStringDebug());
    }
    return result.toString();
  }

  static <A> A firstNonNull(A first, A second) {
    if (first != null) {
      return first;
    } else if (second != null) {
      return second;
    } else {
      throw new NullPointerException();
    }
  }

  /* --------------------------------------------------------- */
  /* Utility routines for debugging CFG building */
  /* --------------------------------------------------------- */

  /**
   * Print a set of {@link Block}s and the edges between them. This is useful for examining the
   * results of phase two.
   *
   * @param blocks the blocks to print
   */
  protected static void printBlocks(Set<Block> blocks) {
    for (Block b : blocks) {
      System.out.print(b.getUid() + ": " + b);
      switch (b.getType()) {
        case REGULAR_BLOCK:
        case SPECIAL_BLOCK:
          {
            Block succ = ((SingleSuccessorBlockImpl) b).getSuccessor();
            System.out.println(" -> " + (succ != null ? succ.getUid() : "||"));
            break;
          }
        case EXCEPTION_BLOCK:
          {
            Block succ = ((SingleSuccessorBlockImpl) b).getSuccessor();
            System.out.print(" -> " + (succ != null ? succ.getUid() : "||") + " {");
            for (Map.Entry<TypeMirror, Set<Block>> entry :
                ((ExceptionBlockImpl) b).getExceptionalSuccessors().entrySet()) {
              System.out.print(entry.getKey() + " : " + entry.getValue() + ", ");
            }
            System.out.println("}");
            break;
          }
        case CONDITIONAL_BLOCK:
          {
            Block tSucc = ((ConditionalBlockImpl) b).getThenSuccessor();
            Block eSucc = ((ConditionalBlockImpl) b).getElseSuccessor();
            System.out.println(
                " -> T "
                    + (tSucc != null ? tSucc.getUid() : "||")
                    + " F "
                    + (eSucc != null ? eSucc.getUid() : "||"));
            break;
          }
      }
    }
  }
}
