"""프롬프트 레지스트리 - 버전 관리 및 재현 가능성 보장."""

from __future__ import annotations

from pathlib import Path
from typing import Dict, List, Optional

import yaml


class PromptRegistry:
    """프롬프트 템플릿 버전을 관리하고 변경 이력을 추적한다."""

    def __init__(self, templates_dir: Path):
        self.templates_dir = templates_dir

    def list_versions(self) -> List[str]:
        """사용 가능한 템플릿 버전 목록을 반환한다 (최신순)."""
        yamls = sorted(self.templates_dir.glob("v*.yaml"), reverse=True)
        return [p.stem for p in yamls]

    def latest_version(self) -> Optional[str]:
        versions = self.list_versions()
        return versions[0] if versions else None

    def load_template(self, version: str) -> Dict:
        path = self.templates_dir / f"{version}.yaml"
        if not path.exists():
            raise FileNotFoundError(f"템플릿 버전 {version}이 없습니다.")
        with open(path, encoding="utf-8") as f:
            return yaml.safe_load(f)

    def compare(self, version_a: str, version_b: str) -> Dict:
        """두 버전의 차이점을 반환한다."""
        a = self.load_template(version_a)
        b = self.load_template(version_b)
        diff = {}
        all_keys = set(a) | set(b)
        for key in all_keys:
            va, vb = a.get(key), b.get(key)
            if va != vb:
                diff[key] = {"old": va, "new": vb}
        return diff

    def save_new_version(self, new_version: str, template: Dict) -> Path:
        """새 버전 템플릿을 저장한다."""
        path = self.templates_dir / f"{new_version}.yaml"
        if path.exists():
            raise FileExistsError(f"버전 {new_version}이 이미 존재합니다.")
        with open(path, "w", encoding="utf-8") as f:
            yaml.dump(template, f, allow_unicode=True, default_flow_style=False)
        return path

    def get_version_for_hash(self, prompt_hash: str, db_session) -> Optional[str]:
        """프롬프트 해시로 사용된 버전을 역조회한다."""
        from harness.logger import JobRecord
        record = db_session.query(JobRecord).filter_by(prompt_hash=prompt_hash).first()
        return record.prompt_version if record else None
