"""Tests for transcript-retention selection — what the prune deletes, safely.

The prune is destructive (it unlinks files on the operator's real ~/.claude), so
the selection logic is proven here against a temp dir before it ever runs live.
"""

from __future__ import annotations

import os
import time
from typing import TYPE_CHECKING

from roboco.runtime.transcript_retention import (
    is_agent_owned_dir,
    select_prunable_transcripts,
)

if TYPE_CHECKING:
    from pathlib import Path

WORKSPACES = "/data/workspaces"
_DAY = 86400


def _touch(path: Path, age_days: float) -> Path:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text("{}\n")
    mtime = time.time() - age_days * _DAY
    os.utime(path, (mtime, mtime))
    return path


def test_is_agent_owned_dir_matches_app_and_workspaces() -> None:
    assert is_agent_owned_dir("-app", WORKSPACES) is True
    assert is_agent_owned_dir("-data-workspaces-roboco-be-dev-1", WORKSPACES) is True
    # The operator's own sessions are never agent-owned.
    assert is_agent_owned_dir("-Users-renzof-Documents-foo", WORKSPACES) is False
    assert is_agent_owned_dir("-home-renzof-code", WORKSPACES) is False


def test_is_agent_owned_dir_rejects_sibling_root_prefixes() -> None:
    # A sibling workspace root that merely shares the encoded prefix without a
    # "-" boundary must NOT be treated as agent-owned, else operator transcripts
    # under it get pruned. Encoded root here is "-data-workspaces".
    assert is_agent_owned_dir("-data-workspaces", WORKSPACES) is True  # exact
    assert is_agent_owned_dir("-data-workspaces2", WORKSPACES) is False
    assert is_agent_owned_dir("-data-workspaces2-project", WORKSPACES) is False
    assert is_agent_owned_dir("-data-workspacesBackup-x", WORKSPACES) is False


def test_is_agent_owned_dir_handles_root_slash_safely() -> None:
    # A pathological "/" workspaces root must not make every dir agent-owned.
    assert is_agent_owned_dir("-Users-renzof-secret", "/") is False
    assert is_agent_owned_dir("-app", "/") is True


def test_select_prunes_only_old_agent_transcripts(tmp_path: Path) -> None:
    projects = tmp_path / "projects"
    old_app = _touch(projects / "-app" / "old.jsonl", age_days=30)
    fresh_app = _touch(projects / "-app" / "fresh.jsonl", age_days=1)
    old_ws = _touch(
        projects / "-data-workspaces-roboco-be-dev-1" / "old.jsonl", age_days=30
    )
    # The operator's own old session — MUST be preserved.
    human_old = _touch(
        projects / "-Users-renzof-Documents-thing" / "old.jsonl", age_days=99
    )

    cutoff = time.time() - 14 * _DAY
    prunable = set(select_prunable_transcripts(projects, WORKSPACES, cutoff))

    assert old_app in prunable
    assert old_ws in prunable
    assert fresh_app not in prunable  # too new
    assert human_old not in prunable  # operator's own session — never pruned


def test_select_ignores_non_jsonl_and_directories(tmp_path: Path) -> None:
    projects = tmp_path / "projects"
    _touch(projects / "-app" / "keep.txt", age_days=30)  # not a transcript
    (projects / "-app" / "subdir.jsonl").mkdir(parents=True)  # a dir named like one
    cutoff = time.time() - 14 * _DAY
    assert select_prunable_transcripts(projects, WORKSPACES, cutoff) == []


def test_select_handles_missing_projects_root(tmp_path: Path) -> None:
    assert select_prunable_transcripts(tmp_path / "nope", WORKSPACES, time.time()) == []
