import sys
import os
import ast
from ast import (
    AsyncFunctionDef,
    FunctionDef,
)
from types import FrameType
from typing import Any, Callable, Optional

from defer.errors import FreeVarsError
from defer.sugar.transformer import RewriteDefer


_DEFER_MARKER = "# defer: parse"
_enabled_files: set[str] = set()


def _load_defer_markers():
    global _enabled_files
    _enabled_files.clear()
    try:
        for root, dirs, filenames in os.walk('src'):
            for filename in filenames:
                if filename.endswith('.py'):
                    relpath = os.path.join(root, filename)
                    abspath = os.path.abspath(relpath)
                    try:
                        with open(abspath, "r", encoding="utf-8", errors="ignore") as f:
                            for i in range(10):
                                line = f.readline()
                                if not line:
                                    break
                                if _DEFER_MARKER in line:
                                    _enabled_files.add(abspath)
                                    break
                    except Exception:
                        pass
    except Exception:
        pass


def install():
    """Only loads markers - does NOT install trace. Trace is lazy."""
    _load_defer_markers()


class _ParseDefer:
    """Lazy defer - trace only activates when @defer is actually used."""
    IDENTITY = lambda *_: None

    def __init__(self, tracefn: Optional[Callable]) -> None:
        self.tracefn = tracefn or self.IDENTITY

    def __call__(self, frame: FrameType, event: str, arg: Any):
        return self.tracefn(frame, event, arg)