"""Skill 注册表 (Anthropic 标准格式)。

每个 skill 是 skills/<name>/ 目录,内含 SKILL.md(带 frontmatter)+ 可选的
references/、scripts/、assets/。启动时只读 frontmatter 做 discovery,完整 SKILL.md
和 references 由 agent 按需加载(渐进披露)。
"""
from __future__ import annotations

import re
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, Optional, Tuple

import yaml


_FRONTMATTER_RE = re.compile(r"^---\n(.*?)\n---\n?", re.DOTALL)


def parse_frontmatter(text: str) -> Tuple[dict, str]:
    """解析 markdown 顶部的 YAML frontmatter。返回 (meta, body)。"""
    m = _FRONTMATTER_RE.match(text)
    if not m:
        return {}, text
    meta = yaml.safe_load(m.group(1)) or {}
    if not isinstance(meta, dict):
        meta = {}
    return meta, text[m.end():]


@dataclass
class Skill:
    name: str
    description: str
    skill_dir: Path

    @property
    def skill_md(self) -> Path:
        return self.skill_dir / "SKILL.md"

    def full_content(self) -> str:
        return self.skill_md.read_text(encoding="utf-8")

    @classmethod
    def from_dir(cls, skill_dir: Path) -> Optional["Skill"]:
        md = skill_dir / "SKILL.md"
        if not md.exists():
            return None
        meta, _ = parse_frontmatter(md.read_text(encoding="utf-8"))
        name = meta.get("name") or skill_dir.name
        desc = meta.get("description") or ""
        if not desc:
            return None  # description 是 discovery 的关键,缺了不收
        return cls(name=name, description=desc, skill_dir=skill_dir)


class SkillRegistry:
    def __init__(self, skills_dir: Path) -> None:
        self.skills_dir = Path(skills_dir)
        self.skills: Dict[str, Skill] = {}
        self._scan()

    def _scan(self) -> None:
        if not self.skills_dir.exists():
            return
        for child in sorted(self.skills_dir.iterdir()):
            if not child.is_dir():
                continue
            skill = Skill.from_dir(child)
            if skill is not None:
                self.skills[skill.name] = skill

    def discovery_block(self) -> str:
        """启动时注入 system prompt 的 skill 列表(name + description)。"""
        if not self.skills:
            return ""
        lines = [f"- **{s.name}**: {s.description}" for s in self.skills.values()]
        return "\n".join(lines)

    def get(self, name: str) -> Optional[Skill]:
        return self.skills.get(name)
