"""L-2: tests for prune_run_logs (run-log rotation).

Verifies that old / surplus *.log files are removed while fresh logs, non-.log
files, the active log, and subdirectories are left intact. Function is
best-effort and must never raise.
"""
import os
import time

from src.agents.launcher import prune_run_logs


def _touch(path, age_days=0):
    with open(path, "w") as f:
        f.write("x")
    mtime = time.time() - age_days * 86400
    os.utime(path, (mtime, mtime))
    return path


def test_old_logs_removed_fresh_kept(tmp_path):
    runs = tmp_path
    fresh = _touch(str(runs / "1.log"), age_days=1)
    old = _touch(str(runs / "2.log"), age_days=40)

    removed = prune_run_logs(str(runs), keep_days=30, keep_max=500)

    assert removed == 1
    assert os.path.exists(fresh)
    assert not os.path.exists(old)


def test_non_log_files_untouched(tmp_path):
    runs = tmp_path
    old_log = _touch(str(runs / "stale.log"), age_days=99)
    keep_txt = _touch(str(runs / "notes.txt"), age_days=99)
    keep_db = _touch(str(runs / "orchestrator.db"), age_days=99)

    prune_run_logs(str(runs), keep_days=30, keep_max=500)

    assert not os.path.exists(old_log)
    assert os.path.exists(keep_txt)
    assert os.path.exists(keep_db)


def test_keep_max_retains_newest(tmp_path):
    runs = tmp_path
    # 5 logs, all recent (within keep_days), increasing age 0..4 days.
    paths = []
    for i in range(5):
        paths.append(_touch(str(runs / f"{i}.log"), age_days=i))

    removed = prune_run_logs(str(runs), keep_days=365, keep_max=2)

    # Only the 2 newest (age 0, 1) survive.
    assert removed == 3
    assert os.path.exists(paths[0])
    assert os.path.exists(paths[1])
    for p in paths[2:]:
        assert not os.path.exists(p)


def test_active_log_never_removed(tmp_path):
    runs = tmp_path
    active = _touch(str(runs / "active.log"), age_days=99)
    other = _touch(str(runs / "other.log"), age_days=99)

    removed = prune_run_logs(
        str(runs), keep_days=30, keep_max=500, active_paths=[active]
    )

    assert removed == 1
    assert os.path.exists(active)
    assert not os.path.exists(other)


def test_subdirs_untouched(tmp_path):
    runs = tmp_path
    sub = runs / "sub.log"
    sub.mkdir()  # a directory that happens to end in .log
    old_log = _touch(str(runs / "old.log"), age_days=99)

    prune_run_logs(str(runs), keep_days=30, keep_max=500)

    assert sub.is_dir()
    assert not os.path.exists(old_log)


def test_missing_dir_is_noop(tmp_path):
    missing = tmp_path / "does-not-exist"
    # Must not raise.
    assert prune_run_logs(str(missing)) == 0
