package org.checkerframework.dataflow.cfg.visualize;

import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.tree.JCTree;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import org.checkerframework.checker.nullness.qual.KeyFor;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.AbstractValue;
import org.checkerframework.dataflow.analysis.Analysis;
import org.checkerframework.dataflow.analysis.Store;
import org.checkerframework.dataflow.analysis.TransferFunction;
import org.checkerframework.dataflow.cfg.ControlFlowGraph;
import org.checkerframework.dataflow.cfg.UnderlyingAST;
import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda;
import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod;
import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.block.Block.BlockType;
import org.checkerframework.dataflow.cfg.block.ConditionalBlock;
import org.checkerframework.dataflow.cfg.block.SpecialBlock;
import org.checkerframework.dataflow.cfg.visualize.AbstractCFGVisualizer.VisualizeWhere;
import org.checkerframework.dataflow.expression.ArrayAccess;
import org.checkerframework.dataflow.expression.ClassName;
import org.checkerframework.dataflow.expression.FieldAccess;
import org.checkerframework.dataflow.expression.LocalVariable;
import org.checkerframework.dataflow.expression.MethodCall;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.TreeUtils;
import org.checkerframework.javacutil.UserError;

/** Generate a graph description in the DOT language of a control graph. */
public class DOTCFGVisualizer<
        V extends AbstractValue<V>, S extends Store<S>, T extends TransferFunction<V, S>>
    extends AbstractCFGVisualizer<V, S, T> {

  /** The output directory. */
  @SuppressWarnings("nullness:initialization.field.uninitialized") // uses init method
  protected String outDir;

  /** The (optional) checker name. Used as a part of the name of the output dot file. */
  protected @Nullable String checkerName;

  /** Mapping from class/method representation to generated dot file. */
  @SuppressWarnings("nullness:initialization.field.uninitialized") // uses init method
  protected Map<String, String> generated;

  /** Terminator for lines that are left-justified. */
  protected static final String leftJustifiedTerminator = "\\l";

  @Override
  @SuppressWarnings("nullness") // assume arguments are set correctly
  public void init(Map<String, Object> args) {
    super.init(args);
    this.outDir = (String) args.get("outdir");
    if (this.outDir == null) {
      throw new BugInCF(
          "outDir should never be null,"
              + " provide it in args when calling DOTCFGVisualizer.init(args).");
    }
    this.checkerName = (String) args.get("checkerName");
    this.generated = new HashMap<>();
  }

  @Override
  public String getSeparator() {
    return leftJustifiedTerminator;
  }

  @Override
  public @Nullable Map<String, Object> visualize(
      ControlFlowGraph cfg, Block entry, @Nullable Analysis<V, S, T> analysis) {

    String dotGraph = visualizeGraph(cfg, entry, analysis);
    String dotFileName = dotOutputFileName(cfg.underlyingAST);

    try {
      FileWriter fStream = new FileWriter(dotFileName);
      BufferedWriter out = new BufferedWriter(fStream);
      out.write(dotGraph);
      out.close();
    } catch (IOException e) {
      throw new UserError("Error creating dot file (is the path valid?): " + dotFileName, e);
    }

    return Collections.singletonMap("dotFileName", dotFileName);
  }

  @SuppressWarnings("keyfor:enhancedfor")
  @Override
  public String visualizeNodes(
      Set<Block> blocks, ControlFlowGraph cfg, @Nullable Analysis<V, S, T> analysis) {

    StringBuilder sbDotNodes = new StringBuilder();

    IdentityHashMap<Block, List<Integer>> processOrder = getProcessOrder(cfg);

    // Definition of all nodes including their labels.
    for (@KeyFor("processOrder") Block v : blocks) {
      sbDotNodes.append("    ").append(v.getUid()).append(" [");
      if (v.getType() == BlockType.CONDITIONAL_BLOCK) {
        sbDotNodes.append("shape=polygon sides=8 ");
      } else if (v.getType() == BlockType.SPECIAL_BLOCK) {
        sbDotNodes.append("shape=oval ");
      } else {
        sbDotNodes.append("shape=rectangle ");
      }
      sbDotNodes.append("label=\"");
      if (verbose) {
        sbDotNodes.append(getProcessOrderSimpleString(processOrder.get(v))).append(getSeparator());
      }
      String strBlock = visualizeBlock(v, analysis);
      if (strBlock.length() == 0) {
        if (v.getType() == BlockType.CONDITIONAL_BLOCK) {
          // The footer of the conditional block.
          sbDotNodes.append("\"];");
        } else {
          // The footer of the block which has no content and is not a special or conditional block.
          sbDotNodes.append("?? empty ??\"];");
        }
      } else {
        sbDotNodes.append(strBlock).append("\"];");
      }
      sbDotNodes.append(System.lineSeparator());
    }
    return sbDotNodes.toString();
  }

  @Override
  protected String visualizeEdge(Object sId, Object eId, String flowRule) {
    return "    " + format(sId) + " -> " + format(eId) + " [label=\"" + flowRule + "\"];";
  }

  @Override
  public String visualizeBlock(Block bb, @Nullable Analysis<V, S, T> analysis) {
    return super.visualizeBlockHelper(bb, analysis, getSeparator());
  }

  @Override
  public String visualizeSpecialBlock(SpecialBlock sbb) {
    return super.visualizeSpecialBlockHelper(sbb);
  }

  @Override
  public String visualizeConditionalBlock(ConditionalBlock cbb) {
    // No extra content in DOT output.
    return "";
  }

  @Override
  public String visualizeBlockTransferInputBefore(Block bb, Analysis<V, S, T> analysis) {
    return super.visualizeBlockTransferInputHelper(
        VisualizeWhere.BEFORE, bb, analysis, getSeparator());
  }

  @Override
  public String visualizeBlockTransferInputAfter(Block bb, Analysis<V, S, T> analysis) {
    return super.visualizeBlockTransferInputHelper(
        VisualizeWhere.AFTER, bb, analysis, getSeparator());
  }

  /**
   * Create a dot file and return its name.
   *
   * @param ast an abstract syntax tree
   * @return the file name used for DOT output
   */
  protected String dotOutputFileName(UnderlyingAST ast) {
    StringBuilder srcLoc = new StringBuilder();
    StringBuilder outFile = new StringBuilder(outDir);

    outFile.append("/");

    if (ast.getKind() == UnderlyingAST.Kind.ARBITRARY_CODE) {
      CFGStatement cfgStatement = (CFGStatement) ast;
      String clsName = cfgStatement.getSimpleClassName();
      outFile.append(clsName);
      outFile.append("-initializer-");
      outFile.append(ast.getUid());

      srcLoc.append("<");
      srcLoc.append(clsName);
      srcLoc.append("::initializer::");
      srcLoc.append(((JCTree) cfgStatement.getCode()).pos);
      srcLoc.append(">");
    } else if (ast.getKind() == UnderlyingAST.Kind.METHOD) {
      CFGMethod cfgMethod = (CFGMethod) ast;
      String clsName = cfgMethod.getSimpleClassName();
      String methodName = cfgMethod.getMethodName();
      StringJoiner params = new StringJoiner(",");
      for (VariableTree tree : cfgMethod.getMethod().getParameters()) {
        params.add(tree.getType().toString());
      }
      outFile.append(clsName);
      outFile.append("-");
      outFile.append(methodName);
      if (params.length() != 0) {
        outFile.append("-");
        outFile.append(params);
      }

      srcLoc.append("<");
      srcLoc.append(clsName);
      srcLoc.append("::");
      srcLoc.append(methodName);
      srcLoc.append("(");
      srcLoc.append(params);
      srcLoc.append(")::");
      srcLoc.append(((JCTree) cfgMethod.getMethod()).pos);
      srcLoc.append(">");
    } else if (ast.getKind() == UnderlyingAST.Kind.LAMBDA) {
      CFGLambda cfgLambda = (CFGLambda) ast;
      String clsName = cfgLambda.getSimpleClassName();
      String methodName = cfgLambda.getMethodName();
      long uid = TreeUtils.treeUids.get(cfgLambda.getCode());
      outFile.append(clsName);
      outFile.append("-");
      outFile.append(methodName);
      outFile.append("-");
      outFile.append(uid);

      srcLoc.append("<");
      srcLoc.append(clsName);
      srcLoc.append("::");
      srcLoc.append(methodName);
      srcLoc.append("(");
      srcLoc.append(cfgLambda.getMethod().getParameters());
      srcLoc.append(")::");
      srcLoc.append(((JCTree) cfgLambda.getCode()).pos);
      srcLoc.append(">");
    } else {
      throw new BugInCF("Unexpected AST kind: " + ast.getKind() + " value: " + ast);
    }
    if (checkerName != null && !checkerName.isEmpty()) {
      outFile.append('-');
      outFile.append(checkerName);
    }
    outFile.append(".dot");

    // make path safe for Windows
    String outFileName = outFile.toString().replace("<", "_").replace(">", "");

    generated.put(srcLoc.toString(), outFileName);

    return outFileName;
  }

  @Override
  protected String format(Object obj) {
    return escapeString(obj);
  }

  @Override
  public String visualizeStoreThisVal(V value) {
    return storeEntryIndent + "this > " + escapeString(value);
  }

  @Override
  public String visualizeStoreLocalVar(LocalVariable localVar, V value) {
    return storeEntryIndent + localVar + " > " + escapeString(value);
  }

  @Override
  public String visualizeStoreFieldVal(FieldAccess fieldAccess, V value) {
    return storeEntryIndent + fieldAccess + " > " + escapeString(value);
  }

  @Override
  public String visualizeStoreArrayVal(ArrayAccess arrayValue, V value) {
    return storeEntryIndent + arrayValue + " > " + escapeString(value);
  }

  @Override
  public String visualizeStoreMethodVals(MethodCall methodCall, V value) {
    return storeEntryIndent + escapeString(methodCall) + " > " + escapeString(value);
  }

  @Override
  public String visualizeStoreClassVals(ClassName className, V value) {
    return storeEntryIndent + className + " > " + escapeString(value);
  }

  @Override
  public String visualizeStoreKeyVal(String keyName, Object value) {
    return storeEntryIndent + keyName + " = " + value;
  }

  /**
   * Escape the input String.
   *
   * @param str the string to be escaped
   * @return the escaped version of the string
   */
  private static String escapeString(final String str) {
    return str.replace("\"", "\\\"").replace("\r", "\\\\r").replace("\n", "\\\\n");
  }

  /**
   * Escape the double quotes from the string representation of the given object.
   *
   * @param obj an object
   * @return an escaped version of the string representation of the object
   */
  private static String escapeString(final Object obj) {
    return escapeString(String.valueOf(obj));
  }

  /**
   * Write a file {@code methods.txt} that contains a mapping from source code location to generated
   * dot file.
   */
  @Override
  public void shutdown() {
    try {
      // Open for append, in case of multiple sub-checkers.
      FileWriter fstream = new FileWriter(outDir + "/methods.txt", true);
      BufferedWriter out = new BufferedWriter(fstream);
      for (Map.Entry<String, String> kv : generated.entrySet()) {
        out.write(kv.getKey());
        out.append("\t");
        out.write(kv.getValue());
        out.append(lineSeparator);
      }
      out.close();
    } catch (IOException e) {
      throw new UserError(
          "Error creating methods.txt file in: " + outDir + "; ensure the path is valid", e);
    }
  }

  @Override
  protected String visualizeGraphHeader() {
    return "digraph {" + lineSeparator;
  }

  @Override
  protected String visualizeGraphFooter() {
    return "}";
  }
}
