package org.jcnc.snow.compiler.semantic.analyzers.statement;

import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.IfNode;
import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.core.Context;
import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.Type;

/**
 * {@code IfAnalyzer} 是用于分析 {@link IfNode} 条件语句的语义分析器。
 * <p>
 * 它负责验证 if 条件表达式的类型合法性，并递归分析 then 分支和 else 分支中的所有子语句。
 * 分析规则如下：
 * <ul>
 *   <li>if 条件必须为 {@link BuiltinType#INT} 类型，用于表示布尔真值；</li>
 *   <li>若条件类型不为 int，将报告语义错误并继续分析；</li>
 *   <li>then 和 else 分支中的语句将分别递归进行语义分析；</li>
 *   <li>若某个子语句无匹配分析器，将回退到默认处理器或报告不支持。</li>
 * </ul>
 */
public class IfAnalyzer implements StatementAnalyzer<IfNode> {

    /**
     * 执行 if 语句的语义分析，包括条件类型检查和分支分析。
     *
     * @param ctx    当前语义分析上下文，提供注册表、错误收集、日志等服务。
     * @param mi     当前模块信息（本实现未直接使用）。
     * @param fn     当前所在函数节点（本实现未直接使用）。
     * @param locals 当前作用域的符号表，提供变量查找支持。
     * @param ifn    要分析的 {@link IfNode} 语法节点，包含条件表达式及两个分支语句块。
     */
    @Override
    public void analyze(Context ctx,
                        ModuleInfo mi,
                        FunctionNode fn,
                        SymbolTable locals,
                        IfNode ifn) {

        // 1. 分析并校验条件表达式类型
        ctx.log("检查 if 条件");
        var exprAnalyzer = ctx.getRegistry().getExpressionAnalyzer(ifn.condition());
        Type cond = exprAnalyzer.analyze(ctx, mi, fn, locals, ifn.condition());
        if (cond != BuiltinType.INT) {
            ctx.getErrors().add(new SemanticError(
                    ifn,
                    "if 条件必须为 int 类型(表示真假)"
            ));
            ctx.log("错误: if 条件类型不为 int");
        }

        // 2. 递归分析 then 分支语句
        for (var stmt : ifn.thenBranch()) {
            var stAnalyzer = ctx.getRegistry().getStatementAnalyzer(stmt);
            if (stAnalyzer != null) {
                stAnalyzer.analyze(ctx, mi, fn, locals, stmt);
            }
        }

        // 3. 递归分析 else 分支语句（若存在）
        for (var stmt : ifn.elseBranch()) {
            var stAnalyzer = ctx.getRegistry().getStatementAnalyzer(stmt);
            if (stAnalyzer != null) {
                stAnalyzer.analyze(ctx, mi, fn, locals, stmt);
            }
        }
    }
}
