package org.jcnc.snow.compiler.parser.core;

import org.jcnc.snow.compiler.lexer.token.TokenType;
import org.jcnc.snow.compiler.parser.base.TopLevelParser;
import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.context.TokenStream;
import org.jcnc.snow.compiler.parser.factory.TopLevelParserFactory;
import org.jcnc.snow.compiler.parser.ast.base.Node;

import java.util.ArrayList;
import java.util.List;

/**
 * {@code ParserEngine} 是语法分析阶段的主控引擎，
 * 负责驱动顶层语法结构（如模块定义、导入语句、函数定义等）的解析流程。
 * <p>
 * 它通过不断读取 TokenStream 中的标记，动态选择合适的解析器（由工厂提供），
 * 并构建对应的抽象语法树（AST）节点。
 * 同时具备跳过空行、处理非法标记等基本容错能力。
 * </p>
 */
public class ParserEngine {

    /** 解析上下文，封装 TokenStream 与语法状态 */
    private final ParserContext ctx;

    /**
     * 构造一个 {@code ParserEngine} 实例。
     *
     * @param ctx 提供语法分析所需的上下文信息（如 Token 流）
     */
    public ParserEngine(ParserContext ctx) {
        this.ctx = ctx;
    }

    /**
     * 启动语法解析流程，提取所有顶层 AST 节点。
     * <p>
     * 该方法会循环调用 {@link TopLevelParserFactory} 选择合适解析器，
     * 并将解析结果存入返回列表，直到遇到文件结束符（EOF）。
     * </p>
     *
     * @return 顶层 AST 节点列表（如模块、导入、函数等）
     * @throws IllegalStateException 若遇到无法识别的顶层标记
     */
    public List<Node> parse() {
        List<Node> nodes = new ArrayList<>();
        TokenStream ts = ctx.getTokens();

        while (ts.isAtEnd()) {
            // 跳过 NEWLINE 以增强容错性
            if (ts.peek().getType() == TokenType.NEWLINE) {
                ts.next();
                continue;
            }

            // 当前词素作为解析关键字（如 module, import）
            String lex = ts.peek().getLexeme();

            TopLevelParser parser = TopLevelParserFactory.get(lex);
            if (parser == null) {
                throw new IllegalStateException("意外的顶级标记: " + lex);
            }

            // 执行对应解析器
            nodes.add(parser.parse(ctx));
        }

        return nodes;
    }
}