"""StubGen 转换器模块 - 将 Python 文件转换为存根格式"""
from __future__ import annotations
import ast
import re
import fnmatch
from typing import List, Dict
from lib.core.SymbolUtils import IsListAnnotation


class PythonToStubConverter:
    """将 Python 文件转换为存根格式"""

    # __include 别名映射表 {alias: ModuleName}
    IncludeAliasMap: Dict[str, str] = {}

    # 变量排除列表 - 匹配这些模式的变量不会被添加到存根文件
    VarExcludeList: List[str] = []

    # 宏排除列表 - 匹配这些模式的宏不会被添加到存根文件
    MacroExcludeList: List[str] = []

    @classmethod
    def SetIncludeAliasMap(cls, alias_map: Dict[str, str]) -> None:
        """设置 __include 别名映射表"""
        cls.IncludeAliasMap = alias_map

    @classmethod
    def SetVarExcludeList(cls, exclude_list: List[str]) -> None:
        """设置变量排除列表"""
        cls.VarExcludeList = exclude_list

    @classmethod
    def SetMacroExcludeList(cls, exclude_list: List[str]) -> None:
        """设置宏排除列表"""
        cls.MacroExcludeList = exclude_list

    @classmethod
    def _ShouldExcludeVar(cls, VarName: str) -> bool:
        """检查变量是否应该被排除"""
        for pattern in cls.VarExcludeList:
            if fnmatch.fnmatch(VarName, pattern):
                return True
        return False

    @classmethod
    def _ShouldExcludeMacro(cls, MacroName: str) -> bool:
        """检查宏是否应该被排除"""
        for pattern in cls.MacroExcludeList:
            if fnmatch.fnmatch(MacroName, pattern):
                return True
        return False

    @staticmethod
    def convert(PyContent: str, ModuleName: str) -> str:
        """将 Python 代码转换为存根格式"""
        lines: list[str] = PyContent.split('\n')
        StubLines: list[str] = []

        # 添加文件头
        StubLines.append('"""')
        StubLines.append(f'Auto-generated Python stub file from {ModuleName}.py')
        StubLines.append(f'Module: {ModuleName}')
        StubLines.append('"""')
        StubLines.append('')

        # 解析 Python 代码，检查是否已经导入了 t 和 c
        HasImportT: bool = False
        HasImportC: bool = False
        try:
            tree: ast.Module = ast.parse(PyContent)
            for node in tree.body:
                if isinstance(node, ast.Import):
                    for alias in node.names:
                        if alias.name == 't':
                            HasImportT = True
                        elif alias.name == 'c':
                            HasImportC = True
        except:
            pass

        # 添加默认导入（如果源代码中没有）
        if not HasImportT:
            StubLines.append('import t')
        if not HasImportC:
            StubLines.append('import c')
        if not HasImportT or not HasImportC:
            StubLines.append('')

        # 添加 c.CPragma("once")
        # StubLines.append('c.CPragma("once")')
        StubLines.append('')

        # 生成文件级别宏守卫名称
        #FileGuardName = f'__{ModuleName.upper()}_DEFINE__'

        # 添加文件开头宏守卫
        #StubLines.append(f'c.CIfndef({FileGuardName})')
        #StubLines.append(f'{FileGuardName}: t.CDefine')
        #StubLines.append('')

        # 解析 Python 代码，提取类型定义
        try:
            tree = ast.parse(PyContent)

            # 第一遍扫描：收集 Postdefinition 变量
            PostdefVars: dict[str, list[tuple[str, str, ast.AnnAssign]]] = {}  # {ClassName: [(VarName, TypeStr, node), ...]}
            for node in tree.body:
                if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
                    TypeStr: str = PythonToStubConverter._GetTypeString(node.annotation)
                    # 检查是否是 Postdefinition 类型
                    if 't.Postdefinition' in TypeStr:
                        # 提取引用的类名
                        ClassName: str | None = PythonToStubConverter._ExtractPostdefClass(node.annotation)
                        if ClassName:
                            if ClassName not in PostdefVars:
                                PostdefVars[ClassName] = []
                            PostdefVars[ClassName].append((node.target.id, TypeStr, node))

            # 按原始顺序处理节点，保持代码的原始顺序
            PrevType: str | None = None  # 记录前一个节点的类型

            for node in tree.body:
                CurrentType: str | None = None

                if isinstance(node, ast.ClassDef):
                    CurrentType = 'class'
                    # 如果前一个不是类，添加空行分隔
                    if PrevType is not None and PrevType != 'class':
                        StubLines.append('')
                    # 检查是否有对应的 Postdefinition 变量
                    ClassPostdefs: list[tuple[str, str, ast.AnnAssign]] = PostdefVars.get(node.name, [])
                    ClassLines: list[str] = PythonToStubConverter._ConvertClass(
                        node, SourceLines=lines, PostdefVars=ClassPostdefs
                    )
                    StubLines.extend(ClassLines)
                elif isinstance(node, ast.FunctionDef):
                    CurrentType = 'function'
                    # 如果前一个是类或者是第一个函数，添加空行分隔
                    if PrevType == 'class' or (PrevType is not None and PrevType != 'function'):
                        StubLines.append('')
                    FuncLines: list[str] = PythonToStubConverter._ConvertFunction(node, SourceLines=lines)
                    StubLines.extend(FuncLines)
                    StubLines.append('')  # 函数后空行
                elif isinstance(node, ast.AnnAssign):
                    CurrentType = 'variable'
                    # 跳过 Postdefinition 变量（已经在类中处理）
                    TypeStr = PythonToStubConverter._GetTypeString(node.annotation)
                    if 't.Postdefinition' in TypeStr:
                        continue
                    # 检查是否带有 t.CStatic 标志，如果有则不排除
                    HasStatic: bool = 't.CStatic' in TypeStr
                    # 检查变量是否应该被排除
                    ShouldExclude: bool = False
                    if isinstance(node.target, ast.Name) and not HasStatic:
                        VarName: str = node.target.id
                        if PythonToStubConverter._ShouldExcludeVar(VarName):
                            ShouldExclude = True
                    if ShouldExclude:
                        continue
                    # 如果前一个不是变量，添加空行分隔
                    if PrevType is not None and PrevType != 'variable':
                        StubLines.append('')
                    VarLines: list[str] = PythonToStubConverter._ConvertVariable(node, SourceLines=lines)
                    # 移除多余的空行
                    VarLines = [line for line in VarLines if line.strip()]
                    StubLines.extend(VarLines)
                elif isinstance(node, ast.Import):
                    # 处理导入语句
                    CurrentType = 'import'
                    ImportStr: str = PythonToStubConverter._GetImportString(node, SourceLines=lines)
                    if ImportStr:
                        if PrevType is not None and PrevType != 'import':
                            StubLines.append('')
                        StubLines.append(ImportStr)
                elif isinstance(node, ast.Assign):
                    CurrentType = 'variable'
                    # 处理模块级别的全局变量（无类型标注）
                    if PrevType is not None and PrevType != 'variable':
                        StubLines.append('')
                    AssignLines: list[str] = PythonToStubConverter._ConvertGlobalAssign(node)
                    StubLines.extend(AssignLines)
                elif isinstance(node, ast.ImportFrom):
                    # 处理 from ... import ... 语句
                    CurrentType = 'import'
                    ImportStr = PythonToStubConverter._GetImportFromString(node, SourceLines=lines)
                    if ImportStr:
                        if PrevType is not None and PrevType != 'import':
                            StubLines.append('')
                        StubLines.append(ImportStr)
                elif isinstance(node, ast.Expr):
                    # 处理模块级别的宏调用，如 c.CIf(...), c.CEndif()
                    ExprStr: str = PythonToStubConverter._GetExprString(node.value)
                    if ExprStr:
                        CurrentType = 'macro'
                        StubLines.append(ExprStr)
                        StubLines.append('')  # 宏后空行
                elif isinstance(node, ast.If):
                    # 处理模块级别的 if 宏条件，如 if c.CIf(FF_MULTI_PARTITION):
                    IfStr: str = PythonToStubConverter._GetModuleIfMacroString(node)
                    if IfStr:
                        CurrentType = 'macro'
                        StubLines.append(IfStr)
                        StubLines.append('')  # 宏后空行

                if CurrentType:
                    PrevType = CurrentType

            # 添加文件结尾宏守卫
            #StubLines.append('')
            #StubLines.append('c.CEndif()')

        except SyntaxError as e:
            # 如果解析失败，添加注释说明
            StubLines.append(f'# Warning: Failed to parse Python code: {e}')
            StubLines.append('# Original content:')
            StubLines.append('"""')
            StubLines.append(PyContent[:1000])  # 只显示前1000字符
            StubLines.append('"""')

        return '\n'.join(StubLines)

    @staticmethod
    def _ConvertClass(node: ast.ClassDef, SourceLines: list[str] | None = None, PostdefVars: list[tuple[str, str, ast.AnnAssign]] | None = None, indent: int = 0) -> list[str]:
        """转换类定义

        Args:
            node: 类定义节点
            SourceLines: 源代码行列表
            PostdefVars: Postdefinition 变量列表 [(VarName, TypeStr, node), ...]
            indent: 缩进级别（用于嵌套类）
        """
        lines: list[str] = []
        PostdefVars = PostdefVars or []
        IndentStr: str = '    ' * indent

        # 处理类装饰器
        for decorator in node.decorator_list:
            DecoratorStr: str = PythonToStubConverter._GetDecoratorString(decorator)
            if DecoratorStr:
                lines.append(f'{IndentStr}@{DecoratorStr}')

        # 检查是否是结构体、联合体或枚举
        BaseNames: list[str] = [base.attr if isinstance(base, ast.Attribute) else base.id
                      for base in node.bases
                      if isinstance(base, (ast.Name, ast.Attribute))]

        # 保留原始基类
        if node.bases:
            BaseStrs: list[str] = []
            for base in node.bases:
                if isinstance(base, ast.Name):
                    BaseStrs.append(base.id)
                elif isinstance(base, ast.Attribute):
                    BaseStrs.append(f'{base.value.id}.{base.attr}')
                elif isinstance(base, ast.Subscript):
                    # 处理泛型类型，如 memory_block_t[MAX_ORDER + 1]
                    BaseStrs.append(PythonToStubConverter._GetTypeString(base))
            ClassTypeParamStr: str = ''
            if hasattr(node, 'type_params') and node.type_params:
                param_names: list[str] = [tp.name for tp in node.type_params]
                ClassTypeParamStr = f'[{", ".join(param_names)}]'
            if BaseStrs:
                lines.append(f'{IndentStr}class {node.name}{ClassTypeParamStr}({", ".join(BaseStrs)}):')
            else:
                lines.append(f'{IndentStr}class {node.name}{ClassTypeParamStr}:')
        else:
            ClassTypeParamStr = ''
            if hasattr(node, 'type_params') and node.type_params:
                param_names = [tp.name for tp in node.type_params]
                ClassTypeParamStr = f'[{", ".join(param_names)}]'
            lines.append(f'{IndentStr}class {node.name}{ClassTypeParamStr}:')

        # 处理类成员
        HasMembers: bool = False
        seen_member_names: set[str] = set()
        for item in node.body:
            if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
                seen_member_names.add(item.target.id)
        init_members: list[ast.AnnAssign] = []
        for item in node.body:
            if isinstance(item, ast.FunctionDef) and item.name == '__init__':
                for stmt in item.body:
                    if (isinstance(stmt, ast.AnnAssign)
                        and isinstance(stmt.target, ast.Attribute)
                        and isinstance(stmt.target.value, ast.Name)
                        and stmt.target.value.id == 'self'):
                        init_members.append(stmt)
        untyped_self_members: list[ast.Assign] = []
        for m_name in [m.target.attr for m in init_members if isinstance(m.target, ast.Attribute)]:
            seen_member_names.add(m_name)
        for item in node.body:
            if isinstance(item, ast.FunctionDef):
                for stmt in item.body:
                    if (isinstance(stmt, ast.Assign)
                        and len(stmt.targets) == 1
                        and isinstance(stmt.targets[0], ast.Attribute)
                        and isinstance(stmt.targets[0].value, ast.Name)
                        and stmt.targets[0].value.id == 'self'):
                        attr_name: str = stmt.targets[0].attr
                        if attr_name not in seen_member_names:
                            seen_member_names.add(attr_name)
                            untyped_self_members.append(stmt)
        for item in list(node.body) + init_members + untyped_self_members:
            if isinstance(item, ast.Assign):
                if (len(item.targets) == 1
                    and isinstance(item.targets[0], ast.Attribute)
                    and isinstance(item.targets[0].value, ast.Name)
                    and item.targets[0].value.id == 'self'):
                    HasMembers = True
                    MemberIndent: str = IndentStr + '    '
                    attr_name = item.targets[0].attr
                    if attr_name in seen_member_names:
                        continue
                    InferredType: str = 'int'
                    if item.value and isinstance(item.value, ast.Constant):
                        if isinstance(item.value.value, float):
                            InferredType = 'float'
                        elif isinstance(item.value.value, bool):
                            InferredType = 'bool'
                        elif isinstance(item.value.value, str):
                            InferredType = 'str'
                    lines.append(f'{MemberIndent}{attr_name}: {InferredType}')
                else:
                    HasMembers = True
                    MemberIndent = IndentStr + '    '
                    if SourceLines and hasattr(item, 'lineno'):
                        StartLine: int = item.lineno - 1
                        EndLine: int = item.end_lineno if hasattr(item, 'end_lineno') and item.end_lineno else StartLine + 1
                        for i in range(StartLine, min(EndLine, len(SourceLines))):
                            lines.append(MemberIndent + SourceLines[i].lstrip())
            elif isinstance(item, ast.AnnAssign):
                HasMembers = True
                TypeStr: str = PythonToStubConverter._GetTypeString(item.annotation)
                MemberIndent = IndentStr + '    '
                # __provides__/__requires__/__require_must__ 元数据：保留值以便跨模块加载
                if isinstance(item.target, ast.Name) and item.target.id in ('__provides__', '__requires__', '__require_must__'):
                    if item.value is not None:
                        try:
                            value_str: str = ast.unparse(item.value)
                        except Exception:
                            value_str = ''
                        lines.append(f'{MemberIndent}{item.target.id}: {TypeStr} = {value_str}')
                    else:
                        lines.append(f'{MemberIndent}{item.target.id}: {TypeStr}')
                    continue
                # 检查是否是宏变量（类型包含 t.CDefine）
                if 't.CDefine' in TypeStr:
                    # 检查宏变量是否应该被排除
                    if isinstance(item.target, ast.Name):
                        MacroName: str = item.target.id
                        if PythonToStubConverter._ShouldExcludeMacro(MacroName):
                            continue  # 跳过该宏
                    # 宏变量保持原样（包括赋值）
                    if SourceLines and hasattr(item, 'lineno'):
                        StartLine = item.lineno - 1
                        EndLine = item.end_lineno if hasattr(item, 'end_lineno') and item.end_lineno else StartLine + 1
                        for i in range(StartLine, min(EndLine, len(SourceLines))):
                            lines.append(MemberIndent + SourceLines[i].lstrip())
                    else:
                        lines.append(f'{MemberIndent}{item.target.id}: {TypeStr}')
                else:
                    if isinstance(item.target, ast.Attribute):
                        MemberName: str = item.target.attr
                    else:
                        MemberName = item.target.id
                    FinalTypeStr: str = TypeStr
                    if IsListAnnotation(item.annotation):
                        slice_node: ast.AST = item.annotation.slice
                        has_size: bool = False
                        if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2:
                            count_node: ast.AST = slice_node.elts[1]
                            if isinstance(count_node, ast.Constant) and isinstance(count_node.value, int) and count_node.value > 0:
                                has_size = True
                            else:
                                try:
                                    count_expr: str = ast.unparse(count_node)
                                except Exception:
                                    count_expr = ''
                                if count_expr and count_expr != 'None':
                                    has_size = True
                                    elem_type_str: str = PythonToStubConverter._GetTypeString(slice_node.elts[0])
                                    FinalTypeStr = f't.CArray[{elem_type_str}, {count_expr}]'
                        if not has_size:
                            elem_type_str = PythonToStubConverter._GetTypeString(slice_node if not isinstance(slice_node, ast.Tuple) else slice_node.elts[0])
                            init_len: int = 0
                            if item.value is not None:
                                if isinstance(item.value, ast.List):
                                    init_len = len(item.value.elts)
                                elif isinstance(item.value, ast.Constant) and isinstance(item.value.value, str):
                                    init_len = len(item.value.value) + 1
                            if init_len > 0:
                                FinalTypeStr = f't.CArray[{elem_type_str}, {init_len}]'
                            else:
                                FinalTypeStr = f't.CArray[{elem_type_str}, None]'
                    if item.value is not None and isinstance(item.value, ast.Constant):
                        try:
                            value_repr: str = ast.unparse(item.value)
                            lines.append(f'{MemberIndent}{MemberName}: {FinalTypeStr} = {value_repr}')
                        except Exception:
                            lines.append(f'{MemberIndent}{MemberName}: {FinalTypeStr}')
                    else:
                        lines.append(f'{MemberIndent}{MemberName}: {FinalTypeStr}')
            elif isinstance(item, ast.FunctionDef):
                HasMembers = True
                FuncStub: list[str] = PythonToStubConverter._ConvertFunction(item, indent=indent+1, SourceLines=SourceLines, class_name=node.name)
                lines.extend(FuncStub)
            elif isinstance(item, ast.Expr):
                # 处理宏调用，如 c.CIf(...), c.CEndif(), c.CElif(), c.CElse()
                ExprStr: str = PythonToStubConverter._GetExprString(item.value)
                if ExprStr:
                    lines.append(f'{IndentStr}    {ExprStr}')
            elif isinstance(item, ast.If):
                # 处理 if c.CIf(...): 形式的宏条件
                IfStr: str = PythonToStubConverter._get_if_macro_string(item, indent=indent+1)
                if IfStr:
                    lines.append(IfStr)
            elif isinstance(item, ast.ClassDef):
                # 处理嵌套类
                HasMembers = True
                NestedClassLines: list[str] = PythonToStubConverter._ConvertClass(item, SourceLines=SourceLines, PostdefVars=[], indent=indent+1)
                # 移除嵌套类的宏守卫（因为已经在父类的宏守卫内）
                FilteredLines: list[str] = []
                for line in NestedClassLines:
                    # 跳过宏守卫相关行
                    if line.strip().startswith('c.CIfndef(') or line.strip().startswith('c.CEndif()'):
                        continue
                    if ': t.CDefine' in line and '__' in line:
                        continue
                    FilteredLines.append(line)
                lines.extend(FilteredLines)

        if not HasMembers:
            lines.append(f'{IndentStr}    pass')

        # 添加 Postdefinition 变量
        if PostdefVars:
            lines.append('')
            for VarName, TypeStr, _ in PostdefVars:
                lines.append(f'{VarName}: {TypeStr}')

        return lines

    @staticmethod
    def _ConvertFunction(node: ast.FunctionDef, indent: int = 0, SourceLines: list[str] | None = None, class_name: str | None = None) -> list[str]:
        """转换函数定义"""
        lines: list[str] = []
        IndentStr: str = '    ' * indent

        # 检查是否是宏函数（返回类型包含 t.CDefine）
        is_macro_func: bool = False
        if node.returns:
            ReturnType: str = PythonToStubConverter._GetTypeString(node.returns)
            if 't.CDefine' in ReturnType:
                is_macro_func = True

        # 如果是宏函数，检查是否应该被排除
        if is_macro_func:
            if PythonToStubConverter._ShouldExcludeMacro(node.name):
                return lines  # 返回空列表，排除该宏

            # 保持原样（包括代码块）
            if SourceLines:
                StartLine: int = node.lineno - 1
                EndLine: int = node.end_lineno if hasattr(node, 'end_lineno') and node.end_lineno else StartLine + 1
                for i in range(StartLine, min(EndLine, len(SourceLines))):
                    lines.append(SourceLines[i])
                if lines and lines[-1].strip() and not lines[-1].rstrip().endswith(':'):
                    pass
                else:
                    lines.append(f'{IndentStr}    pass')
                return lines

        # 处理函数装饰器
        for decorator in node.decorator_list:
            DecoratorStr: str = PythonToStubConverter._GetDecoratorString(decorator)
            if DecoratorStr:
                lines.append(f'{IndentStr}@{DecoratorStr}')

        # 构建参数列表
        params: list[str] = []
        for arg_idx, arg in enumerate(node.args.args):
            ArgName: str = arg.arg
            if arg.annotation:
                TypeStr: str = PythonToStubConverter._GetTypeString(arg.annotation)
                params.append(f'{ArgName}: {TypeStr}')
            elif class_name and arg_idx == 0 and ArgName == 'self':
                params.append(f'self: {class_name}')
            else:
                params.append(ArgName)

        # 处理 *args
        if node.args.vararg:
            ArgName = node.args.vararg.arg
            if node.args.vararg.annotation:
                TypeStr = PythonToStubConverter._GetTypeString(node.args.vararg.annotation)
                params.append(f'*{ArgName}: {TypeStr}')
            else:
                params.append(f'*{ArgName}')

        # 处理 **kwargs
        if node.args.kwarg:
            ArgName = node.args.kwarg.arg
            if node.args.kwarg.annotation:
                TypeStr = PythonToStubConverter._GetTypeString(node.args.kwarg.annotation)
                params.append(f'**{ArgName}: {TypeStr}')
            else:
                params.append(f'**{ArgName}')

        ParamStr: str = ', '.join(params)

        # 返回类型 - 保持原始类型（不添加t.State）
        if node.returns:
            ReturnType = PythonToStubConverter._GetTypeString(node.returns)
        else:
            ReturnType = 't.CInt'

        TypeParamStr: str = ''
        if hasattr(node, 'type_params') and node.type_params:
            param_names: list[str] = [tp.name for tp in node.type_params]
            TypeParamStr = f'[{", ".join(param_names)}]'

        lines.append(f'{IndentStr}def {node.name}{TypeParamStr}({ParamStr}) -> {ReturnType}: pass')
        return lines

    @staticmethod
    def _ConvertVariable(node: ast.AnnAssign, SourceLines: list[str] | None = None) -> list[str]:
        """转换变量定义"""
        lines: list[str] = []
        if isinstance(node.target, ast.Name):
            VarName: str = node.target.id
            TypeStr: str = PythonToStubConverter._GetTypeString(node.annotation)
            # 检查是否是宏变量（类型包含 t.CDefine）
            if 't.CDefine' in TypeStr:
                # 检查宏变量是否应该被排除
                if PythonToStubConverter._ShouldExcludeMacro(VarName):
                    return lines  # 返回空列表，排除该宏
                # 宏变量保持原样（包括赋值）
                if SourceLines and hasattr(node, 'lineno'):
                    StartLine: int = node.lineno - 1
                    EndLine: int = node.end_lineno if hasattr(node, 'end_lineno') and node.end_lineno else StartLine + 1
                    for i in range(StartLine, min(EndLine, len(SourceLines))):
                        lines.append(SourceLines[i])
                else:
                    lines.append(f'{VarName}: {TypeStr}')
                return lines
            # 非宏变量：不加 t.State
            # 含有 typedef 的变量不加 extern，普通变量需要加 extern
            has_typedef: bool = 't.CTypedef' in TypeStr or 'CTypedef' in TypeStr
            if has_typedef and node.value is not None:
                ValueTypeStr: str = PythonToStubConverter._GetTypeString(node.value)
                lines.append(f'{VarName}: {TypeStr} = {ValueTypeStr}')
            else:
                if not has_typedef and 't.CExtern' not in TypeStr and 't.CStatic' not in TypeStr:
                    TypeStr = f't.CExtern | {TypeStr}'
                lines.append(f'{VarName}: {TypeStr}')
        return lines

    @staticmethod
    def _ConvertGlobalAssign(node: ast.Assign) -> list[str]:
        """转换模块级别的全局变量（无类型标注）"""
        lines: list[str] = []
        if not node.targets or not isinstance(node.targets[0], ast.Name):
            return lines

        VarName: str = node.targets[0].id

        # 跳过私有变量（以下划线开头）
        if VarName.startswith('_'):
            return lines

        # 从值推断类型
        inferred_type: str | None = PythonToStubConverter._InferTypeFromValue(node.value)
        if inferred_type:
            lines.append(f'{VarName}: {inferred_type}')
        else:
            lines.append(f'{VarName}: t.CInt')

        return lines

    @staticmethod
    def _InferTypeFromValue(value: ast.AST) -> str | None:
        """从值推断 C 类型"""
        if isinstance(value, ast.Constant):
            if isinstance(value.value, int):
                return 't.CInt'
            elif isinstance(value.value, float):
                return 't.CDouble'
            elif isinstance(value.value, str):
                return 't.CCharPtr'
            elif isinstance(value.value, bool):
                return 't.CInt'
        elif isinstance(value, ast.List):
            return 't.CVoidPtr'
        elif isinstance(value, ast.Dict):
            return 't.CVoidPtr'
        elif isinstance(value, ast.Name):
            return 't.CInt'
        elif isinstance(value, ast.BinOp):
            left_type: str | None = PythonToStubConverter._InferTypeFromValue(value.left)
            if left_type:
                return left_type
            return 't.CInt'
        elif isinstance(value, ast.Call):
            # 函数调用返回值，假设为指针类型
            if isinstance(value.func, ast.Name):
                func_name: str = value.func.id
                if func_name == 'malloc':
                    return 't.CVoidPtr'
                elif func_name in ('ctypes.cast', 'cast'):
                    return 't.CVoidPtr'
            return 't.CVoidPtr'
        return None

    @staticmethod
    def _GetTypeString(annotation: ast.AST) -> str:
        """获取类型字符串"""
        if isinstance(annotation, ast.Name):
            return annotation.id
        elif isinstance(annotation, ast.Attribute):
            if isinstance(annotation.value, ast.Name):
                return f'{annotation.value.id}.{annotation.attr}'
            else:
                # 处理嵌套属性访问，如 t.attr.packed
                ParentStr: str = PythonToStubConverter._GetTypeString(annotation.value)
                return f'{ParentStr}.{annotation.attr}'
        elif isinstance(annotation, ast.Subscript):
            base: str = PythonToStubConverter._GetTypeString(annotation.value)
            if isinstance(annotation.slice, ast.Tuple):
                slice_strs: list[str] = [PythonToStubConverter._GetTypeString(e) for e in annotation.slice.elts]
                SliceStr: str = ', '.join(slice_strs)
            else:
                SliceStr = PythonToStubConverter._GetTypeString(annotation.slice)
            return f'{base}[{SliceStr}]'
        elif isinstance(annotation, ast.BinOp):
            # 处理 BinOp，如 t.CExtern | fd_table.__set_default__(...)
            left: ast.AST = annotation.left
            right: ast.AST = annotation.right

            # 检查右侧是否是 __set_default__ 调用
            if isinstance(right, ast.Call) and isinstance(right.func, ast.Attribute) and right.func.attr in ('__set_default__', '__set_default'):
                # 去除 __set_default__，保留左侧，右侧替换为函数名部分
                LeftStr: str = PythonToStubConverter._GetTypeString(left)
                RightStr: str = PythonToStubConverter._GetTypeString(right.func.value)
                if isinstance(annotation.op, ast.BitOr):
                    return f'{LeftStr} | {RightStr}'

            LeftStr = PythonToStubConverter._GetTypeString(left)
            RightStr = PythonToStubConverter._GetTypeString(right)
            if isinstance(annotation.op, ast.BitOr):
                return f'{LeftStr} | {RightStr}'
            elif isinstance(annotation.op, ast.Add):
                return f'{LeftStr} + {RightStr}'
            elif isinstance(annotation.op, ast.Sub):
                return f'{LeftStr} - {RightStr}'
            elif isinstance(annotation.op, ast.Mult):
                return f'{LeftStr} * {RightStr}'
            elif isinstance(annotation.op, ast.Div):
                return f'{LeftStr} / {RightStr}'
            elif isinstance(annotation.op, ast.Mod):
                return f'{LeftStr} % {RightStr}'
        elif isinstance(annotation, ast.UnaryOp):
            if isinstance(annotation.op, ast.Not):
                operand: str = PythonToStubConverter._GetTypeString(annotation.operand)
                return f'not {operand}'
            elif isinstance(annotation.op, ast.Invert):
                operand = PythonToStubConverter._GetTypeString(annotation.operand)
                return f'~{operand}'
            elif isinstance(annotation.op, ast.USub):
                operand = PythonToStubConverter._GetTypeString(annotation.operand)
                return f'-{operand}'
        elif isinstance(annotation, ast.Compare):
            # 处理比较操作，如 FF_MAX_SS != FF_MIN_SS
            left: str = PythonToStubConverter._GetTypeString(annotation.left)
            comparators: list[str] = [PythonToStubConverter._GetTypeString(c) for c in annotation.comparators]
            ops: list[str] = []
            for op in annotation.ops:
                if isinstance(op, ast.Eq):
                    ops.append('==')
                elif isinstance(op, ast.NotEq):
                    ops.append('!=')
                elif isinstance(op, ast.Lt):
                    ops.append('<')
                elif isinstance(op, ast.LtE):
                    ops.append('<=')
                elif isinstance(op, ast.Gt):
                    ops.append('>')
                elif isinstance(op, ast.GtE):
                    ops.append('>=')
                else:
                    ops.append('?')
            result: str = left
            for i, op in enumerate(ops):
                result += f' {op} {comparators[i]}'
            return result
        elif isinstance(annotation, ast.Constant):
            return repr(annotation.value)
        elif isinstance(annotation, ast.Index):
            return PythonToStubConverter._GetTypeString(annotation.value)
        elif isinstance(annotation, ast.List):
            # 处理列表，如 [MAX_FILE_DESCRIPTORS]
            elements: list[str] = [PythonToStubConverter._GetTypeString(elem) for elem in annotation.elts]
            return f'[{", ".join(elements)}]'
        elif isinstance(annotation, ast.Call):
            # 处理函数调用形式的类型注解，如 t.Postdefinition(xxa) 或 callable(t.CVoid, app_id = t.CInt)
            # 如果是 __set_default__ 调用，只返回函数名部分
            if isinstance(annotation.func, ast.Attribute) and annotation.func.attr in ('__set_default__', '__set_default'):
                return PythonToStubConverter._GetTypeString(annotation.func.value)

            FuncStr: str = PythonToStubConverter._GetTypeString(annotation.func)
            ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in annotation.args])
            # 处理关键字参数
            keywords_str: str = ', '.join([f'{kw.arg} = {PythonToStubConverter._GetTypeString(kw.value)}' for kw in annotation.keywords])
            # 合并位置参数和关键字参数
            if ArgsStr and keywords_str:
                return f'{FuncStr}({ArgsStr}, {keywords_str})'
            elif keywords_str:
                return f'{FuncStr}({keywords_str})'
            else:
                return f'{FuncStr}({ArgsStr})'
        return 't.CVoid'

    @staticmethod
    def _ExtractPostdefClass(annotation: ast.AST) -> str | None:
        """从 Postdefinition 类型注解中提取类名

        例如：t.Postdefinition(__buddy_system) -> '__buddy_system'
              t.Postdefinition(xxx) | t.CTypedef -> 'xxx'
        """
        # 处理 BinOp (如: t.Postdefinition(xxx) | t.CTypedef)
        if isinstance(annotation, ast.BinOp):
            # 递归检查左操作数
            left_result: str | None = PythonToStubConverter._ExtractPostdefClass(annotation.left)
            if left_result:
                return left_result
            # 递归检查右操作数
            right_result: str | None = PythonToStubConverter._ExtractPostdefClass(annotation.right)
            if right_result:
                return right_result
            return None

        # 处理函数调用 (如: t.Postdefinition(__buddy_system))
        if isinstance(annotation, ast.Call):
            FuncStr: str = PythonToStubConverter._GetTypeString(annotation.func)
            if FuncStr == 't.Postdefinition' and annotation.args:
                # 提取第一个参数
                first_arg: ast.AST = annotation.args[0]
                if isinstance(first_arg, ast.Name):
                    return first_arg.id
                elif isinstance(first_arg, ast.Attribute):
                    return f'{first_arg.value.id}.{first_arg.attr}'

        return None

    @staticmethod
    def _GetImportString(node: ast.Import, SourceLines: list[str] | None = None) -> str:
        """获取导入语句字符串"""
        parts: list[str] = []
        IncludeAliasMap: dict[str, str] = PythonToStubConverter.IncludeAliasMap

        for alias in node.names:
            ModuleName: str = alias.name
            # 检查是否是 __include.xxx 格式的导入
            if ModuleName.startswith('__include.'):
                # 提取别名（xxx 部分）
                SubModule: str = ModuleName[len('__include.'):]
                if SubModule in IncludeAliasMap:
                    # 替换为实际模块路径
                    RealModule: str = IncludeAliasMap[SubModule]
                    if alias.asname:
                        parts.append(f'{RealModule} as {alias.asname}')
                    else:
                        parts.append(f'{RealModule} as {SubModule}')
                else:
                    # 不在映射表中，保持原样
                    if alias.asname:
                        parts.append(f'{ModuleName} as {alias.asname}')
                    else:
                        parts.append(ModuleName)
            else:
                if alias.asname:
                    parts.append(f'{alias.name} as {alias.asname}')
                else:
                    parts.append(alias.name)

        result: str = f'import {", ".join(parts)}'

        # 提取并保留注释
        if SourceLines and hasattr(node, 'lineno'):
            LineIdx: int = node.lineno - 1
            if 0 <= LineIdx < len(SourceLines):
                line: str = SourceLines[LineIdx]
                CommentMatch: re.Match | None = re.search(r'#.*$', line)
                if CommentMatch:
                    result += ' ' + CommentMatch.group(0)

        return result

    @staticmethod
    def _GetImportFromString(node: ast.ImportFrom, SourceLines: list[str] | None = None) -> str:
        """获取 from ... import ... 语句字符串"""
        module: str = node.module or ''
        parts: list[str] = []
        IncludeAliasMap: dict[str, str] = PythonToStubConverter.IncludeAliasMap

        # 处理相对导入 (from . import xxx 或 from ..package import xxx)
        if node.level > 0:
            if module:
                if node.level == 1:
                    full_module: str = f'.{module}'
                else:
                    full_module = '.' * node.level + module
            else:
                full_module = '.' * node.level
            for alias in node.names:
                if alias.asname:
                    parts.append(f'{alias.name} as {alias.asname}')
                else:
                    parts.append(alias.name)
            return f'from {full_module} import {", ".join(parts)}'

        # 提取注释（在生成结果前获取）
        comment: str = ''
        if SourceLines and hasattr(node, 'lineno'):
            LineIdx = node.lineno - 1
            if 0 <= LineIdx < len(SourceLines):
                line = SourceLines[LineIdx]
                CommentMatch: re.Match | None = re.search(r'#.*$', line)
                if CommentMatch:
                    comment = ' ' + CommentMatch.group(0)

        # 检查是否是 from __include import xxx 格式
        if module == '__include':
            for alias in node.names:
                name: str = alias.name
                if name in IncludeAliasMap:
                    # 替换为实际模块路径
                    RealModule: str = IncludeAliasMap[name]
                    if alias.asname:
                        parts.append(f'import {RealModule} as {alias.asname}{comment}')
                    else:
                        parts.append(f'import {RealModule} as {name}{comment}')
                else:
                    # 不在映射表中，保持原样
                    if alias.asname:
                        parts.append(f'from {module} import {name} as {alias.asname}{comment}')
                    else:
                        parts.append(f'from {module} import {name}{comment}')
            return '\n'.join(parts)

        # 普通 from ... import ... 语句
        for alias in node.names:
            if alias.asname:
                parts.append(f'{alias.name} as {alias.asname}')
            else:
                parts.append(alias.name)
        return f'from {module} import {", ".join(parts)}{comment}'

    @staticmethod
    def _GetDecoratorString(decorator: ast.AST) -> str:
        """获取装饰器字符串"""
        if isinstance(decorator, ast.Name):
            return decorator.id
        elif isinstance(decorator, ast.Attribute):
            if isinstance(decorator.value, ast.Name):
                return f'{decorator.value.id}.{decorator.attr}'
            return decorator.attr
        elif isinstance(decorator, ast.Call):
            # 处理带参数的装饰器，如 @c.Attribute(t.attr.packed)
            FuncStr: str = PythonToStubConverter._GetDecoratorString(decorator.func)
            ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in decorator.args])
            return f'{FuncStr}({ArgsStr})'
        return ''

    @staticmethod
    def _GetExprString(expr: ast.AST) -> str:
        """获取表达式字符串（用于宏调用）"""
        if isinstance(expr, ast.Call):
            # 处理函数调用，如 c.CIf(...), c.CEndif(), c.CUndef(...), c.CPragma(...)
            FuncStr: str = PythonToStubConverter._GetDecoratorString(expr.func)
            if FuncStr and ('CIf' in FuncStr or 'CEndif' in FuncStr or 'CElif' in FuncStr or 'CElse' in FuncStr or 'CUndef' in FuncStr or 'CPragma' in FuncStr):
                ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in expr.args])
                return f'{FuncStr}({ArgsStr})' if ArgsStr else f'{FuncStr}()'
        return ''

    @staticmethod
    def _get_if_macro_string(node: ast.If, indent: int = 1) -> str:
        """获取类内部的 if 宏字符串（如 if c.CIf(...):）"""
        IndentStr: str = '    ' * indent
        InnerIndent: str = '    ' * (indent + 1)
        # 检查条件是否是宏调用
        if isinstance(node.test, ast.Call):
            FuncStr: str = PythonToStubConverter._GetDecoratorString(node.test.func)
            if FuncStr and 'CIf' in FuncStr:
                ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in node.test.args])
                result: list[str] = [f'{IndentStr}if {FuncStr}({ArgsStr}):' if ArgsStr else f'{IndentStr}if {FuncStr}():']
                # 处理 if 体内的语句
                for item in node.body:
                    if isinstance(item, ast.AnnAssign):
                        TypeStr: str = PythonToStubConverter._GetTypeString(item.annotation)
                        result.append(f'{InnerIndent}{item.target.id}: {TypeStr}')
                    elif isinstance(item, ast.Expr):
                        ExprStr: str = PythonToStubConverter._GetExprString(item.value)
                        if ExprStr:
                            result.append(f'{InnerIndent}{ExprStr}')
                return '\n'.join(result)
        return ''

    @staticmethod
    def _GetModuleIfMacroString(node: ast.If) -> str:
        """获取模块级别的 if 宏字符串（如 if c.CIf(FF_MULTI_PARTITION):）"""
        return PythonToStubConverter._ProcessIfMacro(node, indent=0)

    @staticmethod
    def _ProcessIfMacro(node: ast.If, indent: int = 0) -> str:
        """处理 if 宏节点，支持 elif 和 else"""
        IndentStr: str = '    ' * indent

        # 检查条件是否是宏调用
        if isinstance(node.test, ast.Call):
            FuncStr: str = PythonToStubConverter._GetDecoratorString(node.test.func)
            if FuncStr and 'CIf' in FuncStr:
                ArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in node.test.args])
                result: list[str] = [f'{IndentStr}if {FuncStr}({ArgsStr}):' if ArgsStr else f'{IndentStr}if {FuncStr}():']
                # 处理 if 体内的语句
                for item in node.body:
                    result.extend(PythonToStubConverter._ProcessMacroBodyItem(item, indent + 1))

                # 处理 elif 和 else
                current: ast.If = node
                while current.orelse:
                    if len(current.orelse) == 1 and isinstance(current.orelse[0], ast.If):
                        # elif 情况
                        elif_node: ast.If = current.orelse[0]
                        if isinstance(elif_node.test, ast.Call):
                            ElifFuncStr: str = PythonToStubConverter._GetDecoratorString(elif_node.test.func)
                            if ElifFuncStr and 'CIf' in ElifFuncStr:
                                ElifArgsStr: str = ', '.join([PythonToStubConverter._GetTypeString(arg) for arg in elif_node.test.args])
                                result.append(f'{IndentStr}elif {ElifFuncStr}({ElifArgsStr}):' if ElifArgsStr else f'{IndentStr}elif {ElifFuncStr}():')
                                for item in elif_node.body:
                                    result.extend(PythonToStubConverter._ProcessMacroBodyItem(item, indent + 1))
                                current = elif_node
                                continue
                        break
                    else:
                        # else 情况
                        result.append(f'{IndentStr}else:')
                        for item in current.orelse:
                            result.extend(PythonToStubConverter._ProcessMacroBodyItem(item, indent + 1))
                        break

                return '\n'.join(result)
        return ''

    @staticmethod
    def _ProcessMacroBodyItem(item: ast.AST, indent: int = 0) -> list[str]:
        """处理宏体内的单个语句"""
        IndentStr: str = '    ' * indent
        result: list[str] = []

        if isinstance(item, ast.ClassDef):
            class_stub: list[str] = PythonToStubConverter._ConvertClass(item)
            for line in class_stub:
                if line.strip():
                    result.append(f'{IndentStr}{line}')
                else:
                    result.append(line)
        elif isinstance(item, ast.FunctionDef):
            FuncStub: list[str] = PythonToStubConverter._ConvertFunction(item, indent=indent)
            result.extend(FuncStub)
        elif isinstance(item, ast.AnnAssign):
            TypeStr: str = PythonToStubConverter._GetTypeString(item.annotation)
            result.append(f'{IndentStr}{item.target.id}: {TypeStr}')
        elif isinstance(item, ast.Expr):
            ExprStr: str = PythonToStubConverter._GetExprString(item.value)
            if ExprStr:
                result.append(f'{IndentStr}{ExprStr}')
        elif isinstance(item, ast.If):
            # 处理嵌套的 if 宏
            NestedIf: str = PythonToStubConverter._ProcessIfMacro(item, indent=indent)
            if NestedIf:
                result.append(NestedIf)

        return result