"""script_run 命名与 aicd/bak 归档。"""

from __future__ import annotations

from datetime import datetime, timezone
from pathlib import Path

from aicd.tools.script_backup import (
    archive_script_to_bak,
    format_script_run_filename,
    policy_allow_under_ai_output_or_workspace,
    sanitize_doc_label,
)


def test_sanitize_doc_label() -> None:
    assert sanitize_doc_label(None) == "adhoc"
    assert sanitize_doc_label("  ") == "adhoc"
    assert "manual" in sanitize_doc_label("output/library/foo/manual_v2.md")
    assert "_" in sanitize_doc_label("a/b\\c")


def test_format_script_run_filename_stable_shape() -> None:
    ts = datetime(2025, 3, 23, 8, 15, 30, tzinfo=timezone.utc)
    fn = format_script_run_filename(ts, "py", ".py", "spec_v1", "a1b2c3d4")
    assert fn.startswith("20250323T081530Z_py_spec_v1_")
    assert fn.endswith(".py")


def test_policy_allow_under_ai_output(tmp_path: Path) -> None:
    ai_out = tmp_path / "proj" / "aicd"
    outside = tmp_path / "other" / "x.txt"

    def _deny(_p: Path) -> None:
        raise PermissionError("blocked")

    pol = policy_allow_under_ai_output_or_workspace(ai_out, _deny)
    pol((ai_out / "bak" / "s.py").resolve())  # does not raise
    try:
        pol(outside)
    except PermissionError as e:
        assert "blocked" in str(e)
    else:
        raise AssertionError("expected PermissionError")


def test_archive_script_to_bak_copies_and_removes_tmp(tmp_path: Path) -> None:
    bak = tmp_path / "aicd" / "bak"
    src = tmp_path / "20250323T081530Z_py_adhoc_x1.py"
    src.write_text("print(1)", encoding="utf-8")

    def _ok(p: Path) -> None:
        return None

    r = archive_script_to_bak(src, bak, policy_check=_ok)
    assert r.get("script_backup_ok") is True
    assert r.get("script_bak_path")
    dest = Path(r["script_bak_path"])
    assert dest.is_file()
    assert dest.read_text(encoding="utf-8") == "print(1)"
    assert not src.exists()
