"""Pass 3: SymbolInserter — 将解析后的符号插入 SymbolTable（主命名空间）"""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from lib.core.SymbolTable import SymbolTable

from lib.core.SymbolData import ModuleSymbols


class SymbolInserter:
    """将解析后的符号插入 SymbolTable 的主命名空间（无前缀）"""

    def __init__(self, symbol_table: SymbolTable) -> None:
        self._symtab: SymbolTable = symbol_table
        self._namespace: str | None = None

    def set_namespace(self, namespace: str) -> None:
        """设置当前模块的命名空间"""
        self._namespace = namespace
        self._symtab.register_namespace(namespace)

    def insert(self, module_symbols: ModuleSymbols) -> list[str]:
        """插入所有符号到主命名空间，返回已加载的符号名列表"""
        loaded: list[str] = []
        file_path: str = module_symbols.file_path
        ns: dict[str, object] = self._symtab._namespaces.get(self._namespace, {}) if self._namespace else {}

        # 插入类符号
        for cls in module_symbols.classes:
            self._symtab._InsertClassSymbol(
                cls.name, cls.type_kind, cls.lineno, file_path,
                cls.members, cls.is_cpython_object, cls.is_packed
            )
            loaded.append(cls.name)
            if self._namespace:
                ns[cls.name] = self._symtab._symbols[cls.name]

            # 插入枚举成员（短名 + 类名.成员名）—— CEnum 和 REnum 共用
            if cls.type_kind in ('enum', 'renum'):
                for member_name, member_value, member_lineno in cls.enum_members:
                    self._symtab._InsertEnumMemberSymbol(member_name, cls.name, member_lineno, file_path, value=member_value)
                    loaded.append(member_name)
                    class_member_name: str = f"{cls.name}.{member_name}"
                    self._symtab._InsertEnumMemberSymbol(class_member_name, cls.name, member_lineno, file_path, value=member_value)
                    loaded.append(class_member_name)
                # REnum: 记录变体名列表到类符号（供 HandlesExprCall 跨模块变体构造识别）
                if cls.type_kind == 'renum':
                    renum_info = self._symtab._symbols[cls.name]
                    renum_info.RenumVariants = [m[0] for m in cls.enum_members]

        # 插入 typedef 符号
        for td in module_symbols.typedefs:
            self._symtab._InsertTypedefSymbol(
                td.name, td.original_type_kind, td.original_class,
                td.lineno, file_path, td.members
            )
            loaded.append(td.name)
            if self._namespace:
                ns[td.name] = self._symtab._symbols[td.name]

        # 插入函数符号
        for func in module_symbols.functions:
            # 优先使用 CTypeInfo（保留符号性），回退到 LLVM 类型字符串
            ret_type = func.ret_ctype if func.ret_ctype else func.ret_type
            self._symtab._InsertFuncSymbol(
                func.name, ret_type, func.param_types,
                func.lineno, file_path, func.is_variadic, func.is_inline
            )
            loaded.append(func.name)
            if self._namespace:
                ns[func.name] = self._symtab._symbols[func.name]

        # 插入 define 符号
        for define in module_symbols.defines:
            self._symtab._InsertDefineSymbol(
                define.name, define.value, define.lineno, file_path
            )
            loaded.append(define.name)
            if self._namespace:
                ns[define.name] = self._symtab._symbols[define.name]

        # 插入匿名类型符号（短名）
        for anon_name, anon_data in module_symbols.anonymous_types.items():
            self._symtab._InsertAnonymousSymbol(
                anon_name, anon_data.is_union, anon_data.members,
                anon_data.lineno, file_path
            )

        return loaded
