from __future__ import annotations
import ast
import warnings
from typing import TYPE_CHECKING

from lib.core.Handles.HandlesBase import CTypeInfo, BuiltinTypeMap, CTypeHelper
from lib.core.ConstEvaluator import ConstEvaluator
from lib.core.SymbolUtils import IsTModule, IsTModulePath, IsListAnnotation
from lib.includes import t
from lib.constants.config import mode as _config_mode

if TYPE_CHECKING:
    from lib.core.SymbolTable import SymbolTable


class TypeAnnotationResolver:
    """从 AST 节点解析类型注解，独立于 CTypeInfo 数据模型。"""

    @staticmethod
    def from_type_name(TypeName: str) -> CTypeInfo:
        """从简单类型名构造 CTypeInfo（不经过 FromStr 字符串解析）"""
        # Handle pointer types like 'CUInt32T *', 'void *', etc.
        ptr_count: int = 0
        base_name: str = TypeName
        while base_name.endswith(' *') or base_name.endswith('*'):
            ptr_count += 1
            base_name = base_name.rstrip(' *').rstrip()

        entry: tuple[type, int] | None = BuiltinTypeMap.Get(base_name)
        if entry:
            TypeClass: type
            base_ptr: int
            TypeClass, base_ptr = entry
            info: CTypeInfo = CTypeInfo()
            info.BaseType = TypeClass
            info.PtrCount = base_ptr + ptr_count
            return info
        # Handle LLVM primitive type names (e.g., 'i64', 'double' from generic type inference)
        llvm_map: dict = CTypeInfo._get_llvm_primitive_map()
        llvm_entry: tuple[type, int] | None = llvm_map.get(base_name)
        if llvm_entry:
            TypeClass: type
            base_ptr: int
            TypeClass, base_ptr = llvm_entry
            info: CTypeInfo = CTypeInfo()
            info.BaseType = TypeClass
            info.PtrCount = base_ptr + ptr_count
            return info
        # Fallback with pointer count
        info: CTypeInfo = CTypeInfo.CreateFromTypeName(TypeName)
        if ptr_count > 0:
            info.PtrCount = ptr_count
        return info

    @staticmethod
    def try_eval_const_expr(node: ast.AST, SymbolTable: SymbolTable) -> int | float | str | None:
        return ConstEvaluator.eval_with_symtab(node, SymbolTable)

    @staticmethod
    def from_node(Node: ast.AST, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """从 AST 节点解析 CTypeInfo

        Args:
            Node: AST 节点（如 ast.Name, ast.Attribute 等）
            SymbolTable: 符号表字典
        """
        if isinstance(Node, ast.Constant):
            return TypeAnnotationResolver._from_node_constant(Node, SymbolTable)
        if isinstance(Node, ast.Name):
            return TypeAnnotationResolver._from_node_name(Node, SymbolTable)
        if isinstance(Node, ast.Call):
            return TypeAnnotationResolver._from_node_call(Node, SymbolTable)
        if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr):
            return TypeAnnotationResolver._from_node_binop(Node, SymbolTable)
        if isinstance(Node, ast.Subscript):
            return TypeAnnotationResolver._from_node_subscript(Node, SymbolTable)
        if isinstance(Node, ast.Attribute):
            return TypeAnnotationResolver._from_node_attribute(Node, SymbolTable)
        return CTypeInfo()

    @staticmethod
    def _from_node_constant(Node: ast.AST, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.Constant 节点"""
        TypeName: str = Node.value
        return TypeAnnotationResolver.from_type_name(TypeName)

    @staticmethod
    def _from_node_name(Node: ast.Name, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.Name 节点"""
        TypeName: str = Node.id
        TypeObj: type | None = CTypeHelper.GetTModuleCType(TypeName)
        if TypeObj is None:
            TypeObj = getattr(t, TypeName, None)
        if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType) and TypeObj is not t.CType:
            if TypeObj == t.CPtr:
                Result: CTypeInfo = CTypeInfo()
                Result.PtrCount = 1
                Result.BaseType = t.CVoid()
                return Result
            if TypeObj == t.State:
                Result: CTypeInfo = CTypeInfo()
                Result.IsState = True
                Result.BaseType = t.CVoid()
                return Result
            Inst: t.CType = TypeObj()
            Result: CTypeInfo = CTypeInfo()
            Result.Name = type(Inst).__name__
            # 存储类修饰符（CExtern, CExport, CInline, CThreadLocal 等）：
            # position 含 STORAGE_CLASS 且不含 BASE → 纯修饰符，无实际类型
            if t.CType.STORAGE_CLASS in TypeObj.position and t.CType.BASE not in TypeObj.position:
                Result.BaseType = t.CVoid()
                Result.Storage = Inst
                return Result
            # 类型限定符（CConst, CVolatile 等）
            if t.CType.TYPE_QUALIFIER in TypeObj.position and t.CType.BASE not in TypeObj.position:
                Result.BaseType = t.CVoid()
                if TypeObj == t.CConst:
                    Result.DataConst = True
                elif TypeObj == t.CVolatile:
                    Result.DataVolatile = True
                return Result
            Result.BaseType = TypeObj
            if hasattr(Inst, 'IsSigned'):
                Result.IsSigned = Inst.IsSigned
            return Result
        # 检查 BuiltinTypeMap（覆盖 VOIDPTR, BYTEPTR 等指针别名）
        builtin_entry: tuple[type, int] | None = BuiltinTypeMap.Get(TypeName)
        if builtin_entry:
            TypeClass: type
            base_ptr: int
            TypeClass, base_ptr = builtin_entry
            Result: CTypeInfo = CTypeInfo()
            Result.BaseType = TypeClass
            Result.PtrCount = base_ptr
            return Result
        if TypeName in SymbolTable:
            Entry: CTypeInfo | dict = SymbolTable[TypeName]
            if Entry:
                if isinstance(Entry, CTypeInfo):
                    if Entry.IsTypedef:
                        if Entry.BaseType and (not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0):
                            Result = Entry.Copy()
                            Result.IsTypedef = True
                            Result.Name = TypeName
                            return Result
                        if Entry.OriginalType:
                            if isinstance(Entry.OriginalType, CTypeInfo) and Entry.OriginalType.IsFuncPtr:
                                Result = CTypeInfo()
                                Result.IsFuncPtr = True
                                Result.FuncPtrReturn = Entry.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
                                Result.FuncPtrParams = list(Entry.OriginalType.FuncPtrParams) if Entry.OriginalType.FuncPtrParams else []
                                Result.IsTypedef = True
                                Result.Name = TypeName
                                return Result
                            elif isinstance(Entry.OriginalType, CTypeInfo):
                                Resolved = Entry.OriginalType.Copy()
                            elif isinstance(Entry.OriginalType, str) and Entry.OriginalType == 'Callable':
                                Result = CTypeInfo()
                                Result.IsFuncPtr = True
                                Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
                                Result.FuncPtrParams = []
                                Result.IsTypedef = True
                                Result.Name = TypeName
                                return Result
                            elif isinstance(Entry.OriginalType, str):
                                Resolved = TypeAnnotationResolver.from_type_name(Entry.OriginalType)
                            else:
                                Resolved = Entry.OriginalType
                            Resolved.IsTypedef = True
                            Resolved.Name = TypeName
                            return Resolved
                        TypeEntry = BuiltinTypeMap.Get(TypeName)
                        if TypeEntry:
                            Result = CTypeInfo()
                            Result.BaseType = TypeEntry[0]()
                            Result.PtrCount = TypeEntry[1]
                            Result.IsTypedef = True
                            Result.Name = TypeName
                            return Result
                        return Entry
                    if Entry.IsEnum:
                        Result = CTypeInfo()
                        Result.BaseType = t.CInt()
                        Result.IsEnum = True
                        Result.Name = TypeName
                        return Result
                    if Entry.IsExceptionClass:
                        Result = CTypeInfo()
                        Result.BaseType = t.CInt()
                        Result.IsExceptionClass = True
                        Result.Name = TypeName
                        return Result
                    if Entry.BaseType is None and (Entry.IsStruct or Entry.Name):
                        Entry.BaseType = t.CStruct(name=TypeName)
                        Entry.IsStruct = True
                    return Entry
                elif isinstance(Entry, dict):
                    if Entry.get('type') == 'typedef':
                        OriginalType = Entry.get('OriginalType', '')
                        if OriginalType:
                            if OriginalType == 'Callable':
                                Result = CTypeInfo()
                                Result.IsFuncPtr = True
                                Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
                                Result.FuncPtrParams = []
                                Result.IsTypedef = True
                                Result.Name = TypeName
                                return Result
                            Resolved = TypeAnnotationResolver.from_type_name(OriginalType)
                            Resolved.IsTypedef = True
                            Resolved.Name = TypeName
                            return Resolved
                        TypeEntry = BuiltinTypeMap.Get(TypeName)
                        if TypeEntry:
                            Result = CTypeInfo()
                            Result.BaseType = TypeEntry[0]()
                            Result.PtrCount = TypeEntry[1]
                            Result.IsTypedef = True
                            Result.Name = TypeName
                            return Result
                        Result = CTypeInfo()
                        Result.BaseType = t._CTypedef(TypeName)
                        Result.IsTypedef = True
                        Result.Name = TypeName
                        return Result
        # 检查 t 类型别名（from t import CInt as myint）
        if hasattr(SymbolTable, '_t_type_symbols'):
            t_cls = SymbolTable._t_type_symbols.get(TypeName)
            if t_cls is not None:
                Result = CTypeInfo()
                Result.BaseType = t_cls
                return Result
        # 特殊处理 str 类型，它应该是 char*（指针）
        if TypeName in ('str', 'bytes'):
            Result = CTypeInfo()
            Result.BaseType = t.CChar()
            Result.PtrCount = 1
            return Result
        return TypeAnnotationResolver.from_type_name(TypeName)

    @staticmethod
    def _from_node_call(Node: ast.Call, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.Call 节点"""
        if isinstance(Node.func, ast.Name) and Node.func.id == 'callable':
            Result: CTypeInfo = CTypeInfo()
            Result.IsFuncPtr = True
            Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
            Result.FuncPtrParams = []
            try:
                if len(Node.args) > 0:
                    RetInfo: CTypeInfo = TypeAnnotationResolver.from_node(Node.args[0], SymbolTable)
                    if RetInfo:
                        Result.FuncPtrReturn = RetInfo
                kw: ast.keyword
                for kw in Node.keywords:
                    ParamInfo: CTypeInfo = TypeAnnotationResolver.from_node(kw.value, SymbolTable)
                    if ParamInfo:
                        Result.FuncPtrParams.append((kw.arg or '', ParamInfo))
            except Exception as _e:
                if _config_mode == "strict":
                    warnings.warn(f"异常被忽略: {_e}")
            return Result
        if isinstance(Node.func, ast.Attribute):
            if isinstance(Node.func.value, ast.Name) and IsTModule(Node.func.value.id, SymbolTable):
                if Node.func.attr == 'Bit' and len(Node.args) > 0:
                    Result: CTypeInfo = CTypeInfo()
                    Result.BaseType = t.CInt()
                    Result.IsBitField = True
                    if isinstance(Node.args[0], ast.Constant) and isinstance(Node.args[0].value, int):
                        Result.BitWidth = Node.args[0].value
                    else:
                        Result.BitWidth = 1
                    return Result
        return CTypeInfo()

    @staticmethod
    def _from_node_binop(Node: ast.BinOp, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.BinOp (BitOr) 节点"""
        LeftInfo: CTypeInfo = TypeAnnotationResolver.from_node(Node.left, SymbolTable)
        RightInfo: CTypeInfo = TypeAnnotationResolver.from_node(Node.right, SymbolTable)

        if LeftInfo.IsState or RightInfo.IsState:
            Result: CTypeInfo = CTypeInfo()
            Result.IsState = True
            NonStateInfo: CTypeInfo = LeftInfo if not LeftInfo.IsState else RightInfo
            StateInfo: CTypeInfo = LeftInfo if LeftInfo.IsState else RightInfo
            if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
                Result.BaseType = NonStateInfo.BaseType
            elif NonStateInfo.IsTypedef and NonStateInfo.Name:
                if NonStateInfo.BaseType and (not isinstance(NonStateInfo.BaseType, (t._CTypedef,)) or NonStateInfo.PtrCount > 0):
                    Result.BaseType = NonStateInfo.BaseType
                    Result.PtrCount = NonStateInfo.PtrCount
                    Result.IsTypedef = True
                    Result.Name = NonStateInfo.Name
                    if NonStateInfo.OriginalType:
                        Result.OriginalType = NonStateInfo.OriginalType
                else:
                    Result.BaseType = t.CStruct(name=NonStateInfo.Name)
                    Result.IsStruct = True
                Result.IsTypedef = True
                Result.Name = NonStateInfo.Name
                if NonStateInfo.OriginalType:
                    Result.OriginalType = NonStateInfo.OriginalType
            else:
                Result.BaseType = t.CVoid()
            Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
            if not Result.Storage:
                Result.Storage = t.CExport()
            if LeftInfo.Storage and not isinstance(LeftInfo.Storage, t.CExport):
                Result.Storage = LeftInfo.Storage
            elif RightInfo.Storage and not isinstance(RightInfo.Storage, t.CExport):
                Result.Storage = RightInfo.Storage
            if LeftInfo.DataConst or RightInfo.DataConst:
                Result.DataConst = True
            if LeftInfo.VarConst or RightInfo.VarConst:
                Result.VarConst = True
            return Result

        if LeftInfo.IsPtr or RightInfo.IsPtr:
            Result = CTypeInfo()
            # 当双方都是指针时（如 (AST | t.CPtr) | t.CPtr），PtrCount 应相加
            # 而非取 max，否则 AST** 会被折叠为 AST*，导致对象切片问题
            if LeftInfo.IsPtr and RightInfo.IsPtr:
                Result.PtrCount = LeftInfo.PtrCount + RightInfo.PtrCount
                # BaseType 优先取非 void 侧（如 AST），而非 t.CPtr 的 void
                if LeftInfo.BaseType and not isinstance(LeftInfo.BaseType, t.CVoid):
                    Result.BaseType = LeftInfo.BaseType
                elif RightInfo.BaseType and not isinstance(RightInfo.BaseType, t.CVoid):
                    Result.BaseType = RightInfo.BaseType
                else:
                    Result.BaseType = t.CUnsignedChar()
            else:
                Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
                NonPtrInfo = LeftInfo if not LeftInfo.IsPtr else RightInfo
                PtrInfo = RightInfo if RightInfo.IsPtr else LeftInfo
                if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
                    Result.BaseType = NonPtrInfo.BaseType
                elif NonPtrInfo.IsTypedef and NonPtrInfo.Name:
                    if NonPtrInfo.BaseType and (not isinstance(NonPtrInfo.BaseType, (t._CTypedef,)) or NonPtrInfo.PtrCount > 0):
                        Result.BaseType = NonPtrInfo.BaseType
                        Result.IsTypedef = True
                        Result.Name = NonPtrInfo.Name
                        if NonPtrInfo.OriginalType:
                            Result.OriginalType = NonPtrInfo.OriginalType
                    else:
                        Result.BaseType = t.CStruct(name=NonPtrInfo.Name)
                        Result.IsStruct = True
                elif PtrInfo.BaseType and (not isinstance(PtrInfo.BaseType, (t._CTypedef,)) or PtrInfo.PtrCount > 0):
                    Result.BaseType = PtrInfo.BaseType
                else:
                    Result.BaseType = t.CUnsignedChar()
            if LeftInfo.DataConst or RightInfo.DataConst:
                Result.DataConst = True
            if LeftInfo.VarConst or RightInfo.VarConst:
                Result.VarConst = True
            if LeftInfo.DataVolatile or RightInfo.DataVolatile:
                Result.DataVolatile = True
            if LeftInfo.VarVolatile or RightInfo.VarVolatile:
                Result.VarVolatile = True
            if LeftInfo.Storage:
                Result.Storage = LeftInfo.Storage
            elif RightInfo.Storage:
                Result.Storage = RightInfo.Storage
            return Result

        if LeftInfo.DataConst or RightInfo.DataConst:
            Result = CTypeInfo()
            BaseTypeSide = LeftInfo if not LeftInfo.DataConst else RightInfo
            QualSide = LeftInfo if LeftInfo.DataConst else RightInfo
            Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
            if not Result.BaseType:
                Result.BaseType = t.CInt()
            Result.DataConst = True
            Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
            if LeftInfo.VarConst or RightInfo.VarConst:
                Result.VarConst = True
            if LeftInfo.DataVolatile or RightInfo.DataVolatile:
                Result.DataVolatile = True
            if LeftInfo.Storage:
                Result.Storage = LeftInfo.Storage
            elif RightInfo.Storage:
                Result.Storage = RightInfo.Storage
            return Result

        if LeftInfo.DataVolatile or RightInfo.DataVolatile:
            Result = CTypeInfo()
            BaseTypeSide = LeftInfo if not LeftInfo.DataVolatile else RightInfo
            QualSide = LeftInfo if LeftInfo.DataVolatile else RightInfo
            Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else QualSide.BaseType
            if not Result.BaseType:
                Result.BaseType = t.CInt()
            Result.DataVolatile = True
            Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
            if LeftInfo.VarConst or RightInfo.VarConst:
                Result.VarConst = True
            if LeftInfo.Storage:
                Result.Storage = LeftInfo.Storage
            elif RightInfo.Storage:
                Result.Storage = RightInfo.Storage
            return Result

        if LeftInfo.Storage or RightInfo.Storage:
            Result = CTypeInfo()
            BaseTypeSide = LeftInfo if not LeftInfo.Storage else RightInfo
            StorageSide = LeftInfo if LeftInfo.Storage else RightInfo
            # CExtern | CExport 等价于 t.State：两边都有 Storage 时设置 IsState
            if BaseTypeSide.IsState or StorageSide.IsState or (LeftInfo.Storage and RightInfo.Storage):
                Result.IsState = True
                Result.BaseType = t.CVoid()
                Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
                return Result
            Result.BaseType = BaseTypeSide.BaseType if BaseTypeSide.BaseType and (not isinstance(BaseTypeSide.BaseType, t.CVoid) or BaseTypeSide.PtrCount > 0) else StorageSide.BaseType
            if not Result.BaseType:
                Result.BaseType = t.CInt()
            Result.Storage = LeftInfo.Storage if LeftInfo.Storage else RightInfo.Storage
            Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
            if LeftInfo.DataConst or RightInfo.DataConst:
                Result.DataConst = True
            if LeftInfo.VarConst or RightInfo.VarConst:
                Result.VarConst = True
            return Result

        # 检查是否有位域类型 (t.Bit)
        if LeftInfo.IsBitField:
            Result = CTypeInfo()
            Result.BaseType = LeftInfo.BaseType if LeftInfo.BaseType else t.CInt()
            Result.IsBitField = True
            Result.BitWidth = LeftInfo.BitWidth
            return Result
        if RightInfo.IsBitField:
            Result = CTypeInfo()
            Result.BaseType = RightInfo.BaseType if RightInfo.BaseType else t.CInt()
            Result.IsBitField = True
            Result.BitWidth = RightInfo.BitWidth
            return Result

        # 处理字节序类型 (t.BigEndian, t.LittleEndian)
        # 合并两侧：保留非字节序侧的实际类型（如 CUInt64T），取字节序侧的 ByteOrder
        if LeftInfo.ByteOrder or RightInfo.ByteOrder:
            Result = CTypeInfo()
            ByteOrderSide: CTypeInfo = LeftInfo if LeftInfo.ByteOrder else RightInfo
            OtherSide: CTypeInfo = RightInfo if LeftInfo.ByteOrder else LeftInfo
            if OtherSide.BaseType and (not isinstance(OtherSide.BaseType, (t._CTypedef,)) or OtherSide.PtrCount > 0):
                Result.BaseType = OtherSide.BaseType
            elif ByteOrderSide.BaseType and (not isinstance(ByteOrderSide.BaseType, (t._CTypedef,)) or ByteOrderSide.PtrCount > 0):
                Result.BaseType = ByteOrderSide.BaseType
            else:
                Result.BaseType = t.CInt()
            Result.ByteOrder = LeftInfo.ByteOrder or RightInfo.ByteOrder
            Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
            return Result

        if LeftInfo.IsFuncPtr or RightInfo.IsFuncPtr:
            Result = CTypeInfo()
            FuncPtrSide = LeftInfo if LeftInfo.IsFuncPtr else RightInfo
            Result.IsFuncPtr = True
            Result.FuncPtrParams = list(FuncPtrSide.FuncPtrParams)
            Result.FuncPtrReturn = FuncPtrSide.FuncPtrReturn
            if LeftInfo.Storage:
                Result.Storage = LeftInfo.Storage
            elif RightInfo.Storage:
                Result.Storage = RightInfo.Storage
            return Result

        if LeftInfo.IsTypedef and RightInfo.BaseType:
            if LeftInfo.BaseType and (not isinstance(LeftInfo.BaseType, (t._CTypedef,)) or LeftInfo.PtrCount > 0):
                Result = LeftInfo.Copy()
                Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
                if RightInfo.Storage:
                    Result.Storage = RightInfo.Storage
                return Result
            return RightInfo
        if RightInfo.IsTypedef and LeftInfo.BaseType:
            if RightInfo.BaseType and (not isinstance(RightInfo.BaseType, (t._CTypedef,)) or RightInfo.PtrCount > 0):
                Result = RightInfo.Copy()
                Result.PtrCount = max(LeftInfo.PtrCount, RightInfo.PtrCount)
                if LeftInfo.Storage:
                    Result.Storage = LeftInfo.Storage
                return Result
            return LeftInfo

        if LeftInfo.BaseType:
            return LeftInfo
        elif RightInfo.BaseType:
            return RightInfo
        return CTypeInfo()

    @staticmethod
    def _from_node_subscript(Node: ast.Subscript, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.Subscript 节点"""
        base: ast.AST = Node.value
        if isinstance(base, ast.Attribute):
            if isinstance(base.value, ast.Name) and IsTModule(base.value.id, SymbolTable) and base.attr == 'Bit':
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.IsBitField = True
                if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int):
                    Result.BitWidth = Node.slice.value
                else:
                    Result.BitWidth = 1
                return Result
        if IsListAnnotation(Node):
            slice_node: ast.AST = Node.slice
            elts: list[ast.AST] = []
            if isinstance(slice_node, ast.Tuple):
                elts = slice_node.elts
            elif isinstance(slice_node, (ast.Attribute, ast.Name, ast.Subscript)):
                elts = [slice_node]
            if elts:
                ElemInfo: CTypeInfo = TypeAnnotationResolver.from_node(elts[0], SymbolTable)
                if ElemInfo and ElemInfo.BaseType:
                    Result: CTypeInfo = CTypeInfo()
                    Result.BaseType = ElemInfo.BaseType
                    Result.PtrCount = ElemInfo.PtrCount
                    Result.ArrayDims = list(ElemInfo.ArrayDims)
                    if len(elts) >= 2:
                        count_val: int | None = TypeAnnotationResolver.try_eval_const_expr(elts[1], SymbolTable)
                        if count_val is not None and isinstance(count_val, int) and count_val > 0:
                            Result.ArrayDims.insert(0, str(count_val))
                        else:
                            Result.PtrCount += 1
                    if ElemInfo.IsPtr and not ElemInfo.ArrayDims:
                        Result.PtrCount = max(Result.PtrCount, 1)
                    return Result
        if isinstance(base, ast.Attribute):
            parts: list[str] = []
            current: ast.AST = base
            while isinstance(current, ast.Attribute):
                parts.insert(0, current.attr)
                current = current.value
            if isinstance(current, ast.Name):
                parts.insert(0, current.id)
            if parts and IsTModule(parts[0], SymbolTable) and parts[-1] == t.CPtr.__name__:
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t.CVoid()
                Result.PtrCount = 1
                slice_node: ast.AST = Node.slice
                if isinstance(slice_node, ast.Subscript):
                    InnerInfo: CTypeInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
                    if InnerInfo:
                        if InnerInfo.PtrCount > 0:
                            Result.PtrCount += InnerInfo.PtrCount
                        if InnerInfo.BaseType and not isinstance(InnerInfo.BaseType, t.CVoid):
                            Result.BaseType = InnerInfo.BaseType
                elif isinstance(slice_node, ast.Attribute):
                    SliceInfo: CTypeInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
                    if SliceInfo:
                        if SliceInfo.IsPtr:
                            Result.PtrCount += SliceInfo.PtrCount
                        elif SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
                            Result.BaseType = SliceInfo.BaseType
                elif isinstance(slice_node, ast.Name):
                    SliceType: type | None = getattr(t, slice_node.id, None)
                    if SliceType == t.CPtr:
                        Result.PtrCount += 1
                    else:
                        SliceInfo = TypeAnnotationResolver.from_node(slice_node, SymbolTable)
                        if SliceInfo and SliceInfo.BaseType and not isinstance(SliceInfo.BaseType, t.CVoid):
                            Result.BaseType = SliceInfo.BaseType
                return Result
            if parts and IsTModule(parts[0], SymbolTable) and parts[-1] == 'Callable':
                Result = CTypeInfo()
                Result.IsFuncPtr = True
                slice_node = Node.slice
                if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2:
                    params_list = slice_node.elts[0]
                    return_node = slice_node.elts[1]
                    ParamTypes = []
                    if isinstance(params_list, ast.List):
                        for elt in params_list.elts:
                            ParamTypeInfo = TypeAnnotationResolver.from_node(elt, SymbolTable)
                            if ParamTypeInfo:
                                ParamTypes.append(('', ParamTypeInfo))
                    if not ParamTypes:
                        ParamTypes.append(('', TypeAnnotationResolver.from_type_name('void')))
                    Result.FuncPtrParams = ParamTypes
                    ReturnTypeInfo = TypeAnnotationResolver.from_node(return_node, SymbolTable)
                    Result.FuncPtrReturn = ReturnTypeInfo if ReturnTypeInfo else CTypeInfo.VoidTypeInfo()
                return Result
        return CTypeInfo()

    @staticmethod
    def _from_node_attribute(Node: ast.Attribute, SymbolTable: dict | SymbolTable) -> CTypeInfo:
        """处理 ast.Attribute 节点"""
        ModuleParts: list[str] = []
        Current: ast.AST = Node
        while isinstance(Current, ast.Attribute):
            ModuleParts.insert(0, Current.attr)
            Current = Current.value

        if isinstance(Current, ast.Name):
            ModuleParts.insert(0, Current.id)

        TypeName: str
        ModulePath: str | None
        if len(ModuleParts) >= 2:
            TypeName = ModuleParts[-1]
            ModulePath = '.'.join(ModuleParts[:-1])
        elif len(ModuleParts) == 1:
            TypeName = ModuleParts[0]
            ModulePath = None
        else:
            return CTypeInfo()

        # 解析 import 别名: 如 import vpsdk.window as window -> window -> vpsdk.window
        if ModulePath:
            resolved: bool = False
            import_aliases: dict = SymbolTable.import_aliases
            if ModulePath in import_aliases:
                ModulePath = import_aliases[ModulePath]
                resolved = True
            if not resolved and ModulePath in SymbolTable:
                entry: CTypeInfo = SymbolTable[ModulePath]
                if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
                    resolved_name = entry.ResolvedModule
                    if resolved_name:
                        ModulePath = resolved_name

        if ModulePath and IsTModulePath(ModulePath):
            TypeClass: type | None = CTypeHelper.GetTModuleCType(TypeName)
            if TypeClass is None:
                TypeClass = getattr(t, TypeName, None)
            if TypeClass is not None and TypeClass.HasPosition(t.CType.POINTER):
                Info: CTypeInfo = CTypeInfo()
                Info.PtrCount = 1
                if TypeClass == t.CArrayPtr:
                    Info.IsArrayPtr = True
                Info.BaseType = t.CVoid
                return Info
            if TypeClass is not None and TypeClass.IsStorageClass():
                Info: CTypeInfo = CTypeInfo()
                Info.Storage = TypeClass()
                if TypeClass == t.State:
                    Info.IsState = True
                    Info.BaseType = t.CVoid()
                return Info
            if TypeClass is not None and TypeClass.IsTypeQualifier():
                Info: CTypeInfo = CTypeInfo()
                if TypeClass == t.CConst:
                    Info.DataConst = True
                elif TypeClass == t.CVolatile:
                    Info.DataVolatile = True
                return Info
            if TypeClass is not None and TypeClass in (t.BigEndian, t.LittleEndian):
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.ByteOrder = 'big' if TypeClass == t.BigEndian else 'little'
                return Result
            if (TypeClass is not None
                and isinstance(TypeClass, type)
                and issubclass(TypeClass, t.CType)
                and TypeClass is not t.CType
                and TypeClass.HasPosition(t.CType.BASE)):
                if TypeClass == t.State:
                    Result: CTypeInfo = CTypeInfo()
                    Result.IsState = True
                    Result.BaseType = t.CVoid()
                    return Result
                Inst: t.CType = TypeClass()
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = TypeClass
                Result.Name = type(Inst).__name__
                if hasattr(Inst, 'IsSigned'):
                    Result.IsSigned = Inst.IsSigned
                return Result
            CNAME: str | None = CTypeHelper.GetCName(TypeName)
            if CNAME:
                return TypeAnnotationResolver.from_type_name(CNAME)

            # 处理字节序类型
            if TypeName == 'BigEndian':
                Result = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.ByteOrder = 'big'
                return Result
            if TypeName == 'LittleEndian':
                Result = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.ByteOrder = 'little'
                return Result

        FullName: str = f"{ModulePath}.{TypeName}" if ModulePath else TypeName

        if TypeName in SymbolTable:
            Entry: CTypeInfo = SymbolTable[TypeName]
            if Entry and Entry.IsTypedef:
                Resolved: CTypeInfo = Entry.Copy()
                if Resolved.BaseType is None:
                    Resolved.BaseType = t._CTypedef(TypeName)
                return Resolved
            if Entry and Entry.IsEnum:
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.IsEnum = True
                Result.Name = TypeName
                return Result
            if Entry and Entry.IsExceptionClass:
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t.CInt()
                Result.IsExceptionClass = True
                Result.Name = TypeName
                return Result
            if Entry:
                Result: CTypeInfo = Entry.Copy()
                if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
                    Result.BaseType = t.CStruct(name=TypeName)
                    Result.IsStruct = True
                return Result
            return CTypeInfo()

        if FullName in SymbolTable:
            Info: CTypeInfo = SymbolTable[FullName]
            if Info and Info.IsTypedef:
                # 优先用 BaseType 解析（如 VOIDPTR 已解析为 BaseType=CVoid, PtrCount=1）
                if Info.BaseType and (not isinstance(Info.BaseType, (t._CTypedef,)) or Info.PtrCount > 0):
                    Result = Info.Copy()
                    Result.IsTypedef = True
                    Result.Name = FullName
                    return Result
                # 再用 OriginalType 解析（字符串如 'void *'，或 CTypeInfo）
                if Info.OriginalType:
                    if isinstance(Info.OriginalType, CTypeInfo) and Info.OriginalType.IsFuncPtr:
                        Result = CTypeInfo()
                        Result.IsFuncPtr = True
                        Result.FuncPtrReturn = Info.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
                        Result.FuncPtrParams = list(Info.OriginalType.FuncPtrParams) if Info.OriginalType.FuncPtrParams else []
                        Result.IsTypedef = True
                        Result.Name = FullName
                        return Result
                    elif isinstance(Info.OriginalType, CTypeInfo):
                        Resolved: CTypeInfo = Info.OriginalType.Copy()
                    elif isinstance(Info.OriginalType, str) and Info.OriginalType == 'Callable':
                        Result = CTypeInfo()
                        Result.IsFuncPtr = True
                        Result.FuncPtrReturn = CTypeInfo.VoidTypeInfo()
                        Result.FuncPtrParams = []
                        Result.IsTypedef = True
                        Result.Name = FullName
                        return Result
                    elif isinstance(Info.OriginalType, str):
                        Resolved = TypeAnnotationResolver.from_type_name(Info.OriginalType)
                    else:
                        Resolved = Info.OriginalType
                    if Resolved and Resolved.BaseType:
                        Resolved.IsTypedef = True
                        Resolved.Name = FullName
                        return Resolved
                # 回退：保持原逻辑但设置 Name = FullName（供后续 TypeConvert 查找）
                Result: CTypeInfo = CTypeInfo()
                Result.BaseType = t._CTypedef(TypeName)
                Result.IsTypedef = True
                Result.Name = FullName
                return Result
            if Info:
                Result: CTypeInfo = Info.Copy()
                if Result.BaseType is None and (Result.IsStruct or Result.IsCpythonObject or Result.Name):
                    Result.BaseType = t.CStruct(name=TypeName)
                    Result.IsStruct = True
                return Result
            return CTypeInfo()

        return CTypeInfo()
