from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from lib.core.translator import Translator
from lib.core.Handles.HandlesBase import BaseHandle
import ast
import llvmlite.ir as ir


class BodyHandle(BaseHandle):
    def __init__(self, translator: "Translator") -> None:
        super().__init__(translator)

    def HandleBodyLlvm(self, Body: list[ast.stmt]) -> None:
        Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
        for Node in Body:
            if Gen.builder and Gen.builder.block.is_terminated:
                break
            Gen._set_node_info(Node)
            try:
                if isinstance(Node, ast.Expr):
                    self.HandleExprLlvm(Node.value)
                elif isinstance(Node, ast.Return):
                    self.Trans.ReturnHandler._HandleReturnLlvm(Node)
                elif isinstance(Node, ast.Assign):
                    self.Trans.AssignHandler._HandleAssignLlvm(Node)
                elif isinstance(Node, ast.AugAssign):
                    self.Trans.AugAssignHandler._HandleAugAssignLlvm(Node)
                elif isinstance(Node, ast.AnnAssign):
                    self.Trans.AnnAssignHandler._HandleAnnAssignLlvm(Node)
                elif isinstance(Node, ast.If):
                    self.Trans.IfHandler._HandleIfLlvm(Node)
                elif isinstance(Node, ast.For):
                    self.Trans.ForHandler._HandleForLlvm(Node)
                elif isinstance(Node, ast.While):
                    self.Trans.WhileHandler._HandleWhileLlvm(Node)
                elif isinstance(Node, ast.Break):
                    if Gen.loop_break_targets:
                        Gen.builder.branch(Gen.loop_break_targets[-1])
                elif isinstance(Node, ast.Continue):
                    if Gen.loop_continue_targets:
                        Gen.builder.branch(Gen.loop_continue_targets[-1])
                elif isinstance(Node, ast.With):
                    self.Trans.WithHandler._HandleWithLlvm(Node)
                elif isinstance(Node, ast.ClassDef):
                    pass
                elif getattr(ast, 'Match', None) and isinstance(Node, ast.Match):
                    self.Trans.MatchHandler._HandleMatchLlvm(Node)
                elif isinstance(Node, ast.Try):
                    self.Trans.TryHandler._HandleTryLlvm(Node)
                elif isinstance(Node, ast.Raise):
                    self.Trans.RaiseHandler._HandleRaiseLlvm(Node)
                elif isinstance(Node, ast.Assert):
                    self.Trans.AssertHandler._HandleAssertLlvm(Node)
                elif isinstance(Node, ast.Global):
                    self.Trans.ForHandler._HandleGlobalLlvm(Node)
                elif isinstance(Node, ast.FunctionDef):
                    self.Trans.ForHandler._HandleNestedFunctionLlvm(Node)
                elif isinstance(Node, ast.Nonlocal):
                    self.Trans.ForHandler._HandleNonlocalLlvm(Node)
                elif isinstance(Node, ast.Delete):
                    self.Trans.DeleteHandler._HandleDeleteLlvm(Node)
            except Exception as e:
                lineno: int = getattr(Node, 'lineno', 0)
                source_line: str | None = Gen._get_source_line(lineno)
                src_file: str = Gen._current_source_file or ''
                src_path: str = src_file if src_file else 'unknown'
                line_info: str = "源代码 (%s, line %d)" % (src_path, lineno)
                if source_line:
                    line_info += ":\n    %d | %s" % (lineno, source_line)
                self.Trans._ErrorStack.append((type(e).__name__, str(e), line_info))
                raise
            if Gen.builder and not Gen.builder.block.is_terminated:
                Gen._EmitTempFrees()

    def HandleExprLlvm(self, Node: ast.expr, VarType: ir.Type | None = None) -> ir.Value | None:
        return self.Trans.ExprHandler.HandleExprLlvm(Node, VarType)