package click.kamil.springstatemachineexporter.ast.common;

import org.eclipse.jdt.core.dom.*;
import java.util.*;

public class ControlFlowGraph {
    private final MethodDeclaration method;
    private final CfgNode entryNode = new CfgNode(null, CfgNodeType.ENTRY);
    private final CfgNode exitNode = new CfgNode(null, CfgNodeType.EXIT);
    private final List<CfgNode> nodes = new ArrayList<>();

    public enum CfgNodeType {
        ENTRY,
        EXIT,
        STATEMENT
    }

    public static class CfgNode {
        private final ASTNode astNode;
        private final CfgNodeType type;
        private final Set<CfgNode> predecessors = new HashSet<>();
        private final Set<CfgNode> successors = new HashSet<>();

        public CfgNode(ASTNode astNode, CfgNodeType type) {
            this.astNode = astNode;
            this.type = type;
        }

        public ASTNode getAstNode() {
            return astNode;
        }

        public CfgNodeType getType() {
            return type;
        }

        public Set<CfgNode> getPredecessors() {
            return predecessors;
        }

        public Set<CfgNode> getSuccessors() {
            return successors;
        }

        public void addSuccessor(CfgNode succ) {
            if (succ != null) {
                this.successors.add(succ);
                succ.predecessors.add(this);
            }
        }
    }

    public ControlFlowGraph(MethodDeclaration method) {
        this.method = method;
        this.nodes.add(entryNode);
        this.nodes.add(exitNode);
    }

    public MethodDeclaration getMethod() {
        return method;
    }

    public CfgNode getEntryNode() {
        return entryNode;
    }

    public CfgNode getExitNode() {
        return exitNode;
    }

    public List<CfgNode> getNodes() {
        return nodes;
    }

    public void addNode(CfgNode node) {
        this.nodes.add(node);
    }
}
