"""프롬프트 아카이브 실행 — v0.5.14 정책.

각 step 디렉토리에서 최신 3개 버전만 `_base`에 유지, 나머지는
`_archive/<step>/<version>/`로 `git mv`. 히스토리 보존.

사용:
    python backend/scripts/archive_prompts.py              # dry-run
    python backend/scripts/archive_prompts.py --apply      # 실제 이동
    python backend/scripts/archive_prompts.py --keep 5     # step당 5개 유지
"""
from __future__ import annotations

import argparse
import subprocess
import sys
from pathlib import Path

_BACKEND = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(_BACKEND))

from app.modules.prompt_loader import _version_sort_key  # noqa: E402

PROJECT_ROOT = _BACKEND.parent
PROMPTS_BASE = PROJECT_ROOT / "prompts" / "_base"
PROMPTS_ARCHIVE = PROJECT_ROOT / "prompts" / "_archive"


def plan(keep: int):
    moves = []
    for step_dir in sorted(PROMPTS_BASE.iterdir()):
        if not step_dir.is_dir():
            continue
        versions = sorted(
            [d.name for d in step_dir.iterdir() if d.is_dir()],
            key=_version_sort_key,
            reverse=True,
        )
        if len(versions) <= keep:
            continue
        for old in versions[keep:]:
            src = step_dir / old
            dst = PROMPTS_ARCHIVE / step_dir.name / old
            moves.append((step_dir.name, old, src, dst))
    return moves


def apply_moves(moves):
    """return (success, failed) counts."""
    success = 0
    failed = 0
    for step, ver, src, dst in moves:
        dst.parent.mkdir(parents=True, exist_ok=True)
        try:
            subprocess.run(
                ["git", "mv", str(src), str(dst)],
                check=True,
                cwd=str(PROJECT_ROOT),
            )
            success += 1
        except subprocess.CalledProcessError as exc:
            print(f"[FAIL] {step}/{ver}: {exc}")
            failed += 1
    return success, failed


def main():
    ap = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    ap.add_argument("--apply", action="store_true", help="실제 이동 (생략 시 dry-run)")
    ap.add_argument("--keep", type=int, default=3, help="step당 최신 N개 유지 (기본 3)")
    args = ap.parse_args()

    if not PROMPTS_BASE.exists():
        print(f"Not found: {PROMPTS_BASE}")
        return 1
    moves = plan(keep=args.keep)
    print(f"Candidates: {len(moves)} directories to archive (keep={args.keep})\n")
    by_step = {}
    for step, ver, _src, _dst in moves:
        by_step.setdefault(step, []).append(ver)
    for step in sorted(by_step):
        vers = by_step[step]
        print(f"  {step}: {len(vers)} to archive")
        for v in sorted(vers, key=_version_sort_key):
            print(f"      - {v}")
    if args.apply:
        print()
        success, failed = apply_moves(moves)
        print(f"Moved {success}/{len(moves)} directories (failed: {failed}).")
        return 2 if failed > 0 else 0
    else:
        print("\n(dry-run) pass --apply to execute")
        return 0


if __name__ == "__main__":
    sys.exit(main())
