"""Session-scoped temporary directory lifecycle helpers."""

from __future__ import annotations

import atexit
import shutil
import tempfile
import time
from pathlib import Path

CASCADE_SESSION_PREFIX = "cascade_session_"

_session_root: Path | None = None
_previous_tempdir: str | None = None
_atexit_registered = False


def sweep_stale_session_dirs(
    *,
    base_dir: Path | None = None,
    max_age_seconds: int = 24 * 60 * 60,
    now: float | None = None,
) -> list[Path]:
    """Remove stale cascade session temp directories.

    Args:
        base_dir: Base temp directory to inspect. Defaults to system temp dir.
        max_age_seconds: Minimum age before a session directory is considered stale.
        now: Timestamp override for deterministic tests.

    Returns:
        List of removed session directory paths.
    """
    current_time = time.time() if now is None else now
    temp_base = Path(base_dir) if base_dir is not None else Path(tempfile.gettempdir())
    removed: list[Path] = []

    if not temp_base.exists():
        return removed

    for candidate in temp_base.glob(f"{CASCADE_SESSION_PREFIX}*"):
        if not candidate.is_dir():
            continue
        age_seconds = current_time - candidate.stat().st_mtime
        if age_seconds < max_age_seconds:
            continue
        shutil.rmtree(candidate, ignore_errors=True)
        removed.append(candidate)

    return removed


def init_temp_session(
    *,
    base_dir: Path | None = None,
    stale_max_age_seconds: int = 24 * 60 * 60,
) -> Path:
    """Initialize a fresh session temp root and scope ``tempfile`` to it.

    Args:
        base_dir: Base temp directory for the session root. Defaults to system temp dir.
        stale_max_age_seconds: Stale session cleanup threshold.

    Returns:
        Path to the created session root.
    """
    global _session_root, _previous_tempdir, _atexit_registered

    if _session_root is not None:
        cleanup_temp_session()

    temp_base = Path(base_dir) if base_dir is not None else Path(tempfile.gettempdir())
    sweep_stale_session_dirs(base_dir=temp_base, max_age_seconds=stale_max_age_seconds)

    session_root = Path(tempfile.mkdtemp(prefix=CASCADE_SESSION_PREFIX, dir=temp_base))
    _previous_tempdir = tempfile.tempdir
    tempfile.tempdir = str(session_root)
    _session_root = session_root

    if not _atexit_registered:
        atexit.register(cleanup_temp_session)
        _atexit_registered = True

    return session_root


def cleanup_temp_session() -> None:
    """Cleanup current session temp root and restore previous ``tempfile`` config."""
    global _session_root, _previous_tempdir

    if _session_root is not None:
        shutil.rmtree(_session_root, ignore_errors=True)

    tempfile.tempdir = _previous_tempdir
    _session_root = None
    _previous_tempdir = None
