package cfg;

import cfg.CFG.Symbol;

import java.util.Objects;

public class ASTNode {
    private final boolean isTerminal;
    private final ASTNode[] children;
    private final Symbol symbol;

    public ASTNode(Symbol symbol, ASTNode[] children, boolean isTerminal) {
        this.symbol = symbol;
        this.children = children;
        this.isTerminal = isTerminal;
    }

    public ASTNode(Symbol symbol, ASTNode[] children) {
        this(symbol, children, false);
    }

    public ASTNode(Symbol symbol) {
        this(symbol, null, true);
    }

    public String toString() {
        if (this.isTerminal) {
            return this.symbol.toString();
        } else {
            StringBuilder s = new StringBuilder();
            for (ASTNode child : this.getChildren()) {
                s.append(child.toString());
            }
            return s.toString();
        }
    }

    public boolean isTerminal() {
        return this.isTerminal;
    }

    public ASTNode[] getChildren() {
        return this.children;
    }

    public String getValue() {
        return this.symbol.toString();
    }

    public int numChildren() {
        return this.children == null ? 0 : this.children.length;
    }

    public ASTNode getLeftChild() {
        return this.children[0];
    }

    public ASTNode getRightChild() {
        return this.children[this.children.length - 1];
    }

    /**
     * Collapse the parse tree.
     *
     * @return a tree where no nonterminal node has a single child
     */
    public ASTNode collapse() {
        if (this.children == null || this.isTerminal)
            return this;

        // Collapse nodes with a single child
        if (children.length == 1)
            return children[0].collapse();

        for (int i = 0; i < children.length; i++) {
            children[i] = children[i].collapse();
        }
        return this;
    }
}