package org.checkerframework.dataflow.cfg.builder;

import com.sun.source.tree.ClassTree;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.UnaryTree;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import org.checkerframework.dataflow.cfg.UnderlyingAST;
import org.checkerframework.dataflow.cfg.builder.ExtendedNode.ExtendedNodeType;
import org.checkerframework.dataflow.cfg.node.AssignmentNode;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.dataflow.cfg.node.ReturnNode;

/* --------------------------------------------------------- */
/* Phase One */
/* --------------------------------------------------------- */

/**
 * A wrapper object to pass around the result of phase one. For a documentation of the fields see
 * {@link CFGTranslationPhaseOne}.
 */
public class PhaseOneResult {

  final IdentityHashMap<Tree, Set<Node>> treeLookupMap;
  final IdentityHashMap<Tree, Set<Node>> convertedTreeLookupMap;
  final IdentityHashMap<UnaryTree, AssignmentNode> unaryAssignNodeLookupMap;
  final UnderlyingAST underlyingAST;
  final Map<Label, Integer> bindings;
  final ArrayList<ExtendedNode> nodeList;
  final Set<Integer> leaders;
  final List<ReturnNode> returnNodes;
  final Label regularExitLabel;
  final Label exceptionalExitLabel;
  final List<ClassTree> declaredClasses;
  final List<LambdaExpressionTree> declaredLambdas;

  public PhaseOneResult(
      UnderlyingAST underlyingAST,
      IdentityHashMap<Tree, Set<Node>> treeLookupMap,
      IdentityHashMap<Tree, Set<Node>> convertedTreeLookupMap,
      IdentityHashMap<UnaryTree, AssignmentNode> unaryAssignNodeLookupMap,
      ArrayList<ExtendedNode> nodeList,
      Map<Label, Integer> bindings,
      Set<Integer> leaders,
      List<ReturnNode> returnNodes,
      Label regularExitLabel,
      Label exceptionalExitLabel,
      List<ClassTree> declaredClasses,
      List<LambdaExpressionTree> declaredLambdas) {
    this.underlyingAST = underlyingAST;
    this.treeLookupMap = treeLookupMap;
    this.convertedTreeLookupMap = convertedTreeLookupMap;
    this.unaryAssignNodeLookupMap = unaryAssignNodeLookupMap;
    this.nodeList = nodeList;
    this.bindings = bindings;
    this.leaders = leaders;
    this.returnNodes = returnNodes;
    this.regularExitLabel = regularExitLabel;
    this.exceptionalExitLabel = exceptionalExitLabel;
    this.declaredClasses = declaredClasses;
    this.declaredLambdas = declaredLambdas;
  }

  @Override
  public String toString() {
    StringJoiner sj = new StringJoiner(System.lineSeparator());
    for (ExtendedNode n : nodeList) {
      sj.add(nodeToString(n));
    }
    return sj.toString();
  }

  protected String nodeToString(ExtendedNode n) {
    if (n.getType() == ExtendedNodeType.CONDITIONAL_JUMP) {
      ConditionalJump t = (ConditionalJump) n;
      return "TwoTargetConditionalJump("
          + resolveLabel(t.getThenLabel())
          + ", "
          + resolveLabel(t.getElseLabel())
          + ")";
    } else if (n.getType() == ExtendedNodeType.UNCONDITIONAL_JUMP) {
      return "UnconditionalJump(" + resolveLabel(n.getLabel()) + ")";
    } else {
      return n.toString();
    }
  }

  private String resolveLabel(Label label) {
    Integer index = bindings.get(label);
    if (index == null) {
      return "unbound label: " + label;
    }
    return nodeToString(nodeList.get(index));
  }

  /**
   * Returns a representation of a map, one entry per line.
   *
   * @param <K> the key type of the map
   * @param <V> the value type of the map
   * @param map a map
   * @return a representation of a map, one entry per line
   */
  private <K, V> String mapToString(Map<K, V> map) {
    if (map.isEmpty()) {
      return "{}";
    }
    StringJoiner result =
        new StringJoiner(
            String.format("%n    "), String.format("{%n    "), String.format("%n    }"));
    for (Map.Entry<K, V> entry : map.entrySet()) {
      result.add(entry.getKey() + " => " + entry.getValue());
    }
    return result.toString();
  }

  /**
   * Returns a verbose string representation of this, useful for debugging.
   *
   * @return a string representation of this
   */
  public String toStringDebug() {
    StringJoiner result =
        new StringJoiner(
            String.format("%n  "), String.format("PhaseOneResult{%n  "), String.format("%n  }"));
    result.add("treeLookupMap=" + mapToString(treeLookupMap));
    result.add("convertedTreeLookupMap=" + mapToString(convertedTreeLookupMap));
    result.add("unaryAssignNodeLookupMap=" + mapToString(unaryAssignNodeLookupMap));
    result.add("underlyingAST=" + underlyingAST);
    result.add("bindings=" + bindings);
    result.add("nodeList=" + CFGBuilder.extendedNodeCollectionToStringDebug(nodeList));
    result.add("leaders=" + leaders);
    result.add("returnNodes=" + Node.nodeCollectionToString(returnNodes));
    result.add("regularExitLabel=" + regularExitLabel);
    result.add("exceptionalExitLabel=" + exceptionalExitLabel);
    result.add("declaredClasses=" + declaredClasses);
    result.add("declaredLambdas=" + declaredLambdas);
    return result.toString();
  }
}
