"""Pass 4: PackageReexporter — 将符号重新导出到命名空间前缀下"""
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 PackageReexporter:
    """将已解析的符号重新导出到命名空间前缀下（如 memhub.MemPool）"""

    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

    def reexport(self, module_symbols: ModuleSymbols, prefixes: list[str], lineno: int = 0) -> 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 prefix in prefixes:
            # 插入类符号（前缀.类名）
            for cls in module_symbols.classes:
                full_name: str = f"{prefix}.{cls.name}"
                self._symtab._InsertClassSymbol(
                    full_name, cls.type_kind, cls.lineno, file_path,
                    cls.members, cls.is_cpython_object, cls.is_packed
                )
                loaded.append(full_name)
                if self._namespace:
                    ns[full_name] = self._symtab._symbols[full_name]

                # 插入枚举成员（前缀.成员名 + 前缀.类名.成员名）—— CEnum 和 REnum 共用
                if cls.type_kind in ('enum', 'renum'):
                    for member_name, member_value, member_lineno in cls.enum_members:
                        full_member_name: str = f"{prefix}.{member_name}"
                        self._symtab._InsertEnumMemberSymbol(full_member_name, cls.name, member_lineno, file_path, value=member_value)
                        loaded.append(full_member_name)
                        # 同时注册 prefix.ClassName.member_name，以支持 module.Class.MEMBER 三层访问
                        qualified_member_name: str = f"{prefix}.{cls.name}.{member_name}"
                        self._symtab._InsertEnumMemberSymbol(qualified_member_name, cls.name, member_lineno, file_path, value=member_value)
                        loaded.append(qualified_member_name)
                    # REnum: 记录变体名列表到前缀类符号
                    if cls.type_kind == 'renum':
                        renum_info = self._symtab._symbols[full_name]
                        renum_info.RenumVariants = [m[0] for m in cls.enum_members]

            # 插入 typedef 符号（前缀.名称）
            for td in module_symbols.typedefs:
                full_name: str = f"{prefix}.{td.name}"
                self._symtab._InsertTypedefSymbol(
                    full_name, td.original_type_kind, td.original_class,
                    td.lineno, file_path, td.members
                )
                loaded.append(full_name)
                if self._namespace:
                    ns[full_name] = self._symtab._symbols[full_name]

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

            # 插入 define 符号（前缀.名称）
            for define in module_symbols.defines:
                full_name: str = f"{prefix}.{define.name}"
                self._symtab._InsertDefineSymbol(
                    full_name, define.value, define.lineno, file_path
                )
                loaded.append(full_name)
                if self._namespace:
                    ns[full_name] = self._symtab._symbols[full_name]

            # 插入模块别名
            self._symtab._InsertModuleSymbol(prefix, lineno, file_path)

            # 插入匿名类型符号（前缀.名称）
            for anon_name, anon_data in module_symbols.anonymous_types.items():
                full_type_name: str = f"{prefix}.{anon_name}"
                self._symtab._InsertAnonymousSymbol(
                    full_type_name, anon_data.is_union, anon_data.members,
                    anon_data.lineno, file_path
                )

        return loaded
