"""Unit tests for temporary session lifecycle helpers."""

from __future__ import annotations

import os
import tempfile
import time
from pathlib import Path

from cascade_fm.core import temp_session


def test_init_temp_session_scopes_tempfile_to_session_root(tmp_path: Path):
    """Init should create a session root and scope tempfile outputs to it."""
    temp_session.cleanup_temp_session()
    original_tempdir = tempfile.tempdir

    try:
        session_root = temp_session.init_temp_session(base_dir=tmp_path)
        assert session_root.exists()
        assert session_root.parent == tmp_path
        assert session_root.name.startswith(temp_session.CASCADE_SESSION_PREFIX)

        nested = Path(tempfile.mkdtemp(prefix="cascade_test_"))
        assert nested.parent == session_root
    finally:
        temp_session.cleanup_temp_session()

    assert tempfile.tempdir == original_tempdir


def test_cleanup_temp_session_removes_session_root(tmp_path: Path):
    """Cleanup should remove session root and restore tempfile defaults."""
    temp_session.cleanup_temp_session()
    original_tempdir = tempfile.tempdir
    session_root = temp_session.init_temp_session(base_dir=tmp_path)

    assert session_root.exists()
    temp_session.cleanup_temp_session()

    assert not session_root.exists()
    assert tempfile.tempdir == original_tempdir


def test_sweep_stale_session_dirs_only_removes_old_entries(tmp_path: Path):
    """Stale sweep should remove old session dirs and keep fresh ones."""
    old_dir = tmp_path / f"{temp_session.CASCADE_SESSION_PREFIX}old"
    fresh_dir = tmp_path / f"{temp_session.CASCADE_SESSION_PREFIX}fresh"
    other_dir = tmp_path / "not_a_session_dir"

    old_dir.mkdir()
    fresh_dir.mkdir()
    other_dir.mkdir()

    now = time.time()
    old_mtime = now - 2 * 24 * 60 * 60
    fresh_mtime = now - 60

    old_dir.touch()
    fresh_dir.touch()
    other_dir.touch()

    old_dir_stat = old_dir.stat()
    fresh_dir_stat = fresh_dir.stat()
    other_dir_stat = other_dir.stat()

    old_dir_mtime_ns = int(old_mtime * 1_000_000_000)
    fresh_dir_mtime_ns = int(fresh_mtime * 1_000_000_000)

    os.utime(old_dir, ns=(old_dir_stat.st_atime_ns, old_dir_mtime_ns))
    os.utime(fresh_dir, ns=(fresh_dir_stat.st_atime_ns, fresh_dir_mtime_ns))
    os.utime(other_dir, ns=(other_dir_stat.st_atime_ns, old_dir_mtime_ns))

    removed = temp_session.sweep_stale_session_dirs(
        base_dir=tmp_path,
        max_age_seconds=24 * 60 * 60,
        now=now,
    )

    assert old_dir in removed
    assert not old_dir.exists()
    assert fresh_dir.exists()
    assert other_dir.exists()
