#!/usr/bin/env python3
"""gen-skill-docs.py — SKILL.md 표준 템플릿 자동 생성/검증 도구

Usage:
    python3 gen-skill-docs.py [--skills-dir DIR] [--verify|--generate] [--skill NAME] [--dry-run]
"""

import argparse
import json
import sys
from pathlib import Path
from typing import Any

# ---------------------------------------------------------------------------
# 표준 섹션 목록
# ---------------------------------------------------------------------------
REQUIRED_SECTIONS = ["Description", "Trigger", "Usage", "Examples", "Files"]

# ---------------------------------------------------------------------------
# 커스텀 예외
# ---------------------------------------------------------------------------


class SkillsError(Exception):
    """스킬 관련 오류"""


# ---------------------------------------------------------------------------
# 템플릿
# ---------------------------------------------------------------------------
SKILL_MD_TEMPLATE = """\
# {skill_name}

## Description
<!-- 스킬에 대한 설명을 작성하세요 -->

## Trigger
<!-- 이 스킬이 실행되는 조건/트리거를 작성하세요 -->

## Usage
<!-- 사용법을 작성하세요 -->

## Examples
<!-- 사용 예시를 작성하세요 -->

## Files
<!-- 관련 파일 목록을 작성하세요 -->
"""


# ---------------------------------------------------------------------------
# 섹션 검사 헬퍼
# ---------------------------------------------------------------------------
def check_section(content: str, section_name: str) -> bool:
    """content 에 ## <section_name> 헤더가 존재하는지 확인한다."""
    return f"## {section_name}" in content


def find_missing_sections(content: str) -> list[str]:
    """표준 섹션 중 누락된 섹션명 목록을 반환한다."""
    return [s for s in REQUIRED_SECTIONS if not check_section(content, s)]


# ---------------------------------------------------------------------------
# 단일 스킬 SKILL.md 검증
# ---------------------------------------------------------------------------
def verify_skill(skill_dir: Path) -> dict[str, Any]:
    """단일 스킬 디렉토리를 검증하고 결과 dict 를 반환한다."""
    skill_name = skill_dir.name
    skill_md_path = skill_dir / "SKILL.md"

    if not skill_md_path.exists():
        return {
            "skill": skill_name,
            "missing_sections": REQUIRED_SECTIONS[:],
            "status": "non_compliant",
        }

    content = skill_md_path.read_text(encoding="utf-8", errors="ignore")
    missing = find_missing_sections(content)

    return {
        "skill": skill_name,
        "missing_sections": missing,
        "status": "compliant" if not missing else "non_compliant",
    }


# ---------------------------------------------------------------------------
# 전체 스킬 디렉토리 검증
# ---------------------------------------------------------------------------
def verify_skills(skills_dir: str = "~/.claude/skills", skill_name: str | None = None) -> dict[str, Any]:
    """스킬 디렉토리를 스캔하여 SKILL.md 준수 여부를 검증한다."""
    path = Path(skills_dir).expanduser()
    if not path.exists() or not path.is_dir():
        raise SkillsError(f"스킬 디렉토리를 찾을 수 없습니다: {skills_dir}")

    if skill_name is not None:
        skill_path = path / skill_name
        if not skill_path.exists() or not skill_path.is_dir():
            raise SkillsError(f"스킬을 찾을 수 없습니다: {skill_name}")
        skill_dirs = [skill_path]
    else:
        skill_dirs = sorted([d for d in path.iterdir() if d.is_dir()])

    details: list[dict[str, Any]] = []
    for skill_dir in skill_dirs:
        details.append(verify_skill(skill_dir))

    compliant = sum(1 for d in details if d["status"] == "compliant")
    non_compliant = len(details) - compliant

    return {
        "skills_checked": len(details),
        "compliant": compliant,
        "non_compliant": non_compliant,
        "details": details,
    }


# ---------------------------------------------------------------------------
# 단일 스킬 SKILL.md 생성
# ---------------------------------------------------------------------------
def generate_skill_md(skill_dir: str, skill_name: str, dry_run: bool = False) -> str | None:
    """스킬 디렉토리에 SKILL.md 를 생성하거나 미리보기 문자열을 반환한다."""
    path = Path(skill_dir).expanduser()
    if not path.exists() or not path.is_dir():
        raise SkillsError(f"스킬 디렉토리를 찾을 수 없습니다: {skill_dir}")

    content = SKILL_MD_TEMPLATE.format(skill_name=skill_name)

    if dry_run:
        return content

    skill_md_path = path / "SKILL.md"
    skill_md_path.write_text(content, encoding="utf-8")
    return None


# ---------------------------------------------------------------------------
# 전체 스킬 SKILL.md 생성 (누락된 것만)
# ---------------------------------------------------------------------------
def generate_all_skills(skills_dir: str = "~/.claude/skills", dry_run: bool = False) -> list[str]:
    """스킬 디렉토리 전체를 스캔하여 SKILL.md 가 없거나 미준수인 경우 생성한다."""
    path = Path(skills_dir).expanduser()
    if not path.exists() or not path.is_dir():
        raise SkillsError(f"스킬 디렉토리를 찾을 수 없습니다: {skills_dir}")

    generated: list[str] = []
    for skill_path in sorted(path.iterdir()):
        if not skill_path.is_dir():
            continue
        skill_md_path = skill_path / "SKILL.md"
        # 이미 준수하는 SKILL.md 가 있으면 그대로 둠
        if skill_md_path.exists():
            content = skill_md_path.read_text(encoding="utf-8", errors="ignore")
            if not find_missing_sections(content):
                continue
        # 없거나 미준수인 경우 생성
        generate_skill_md(skill_dir=str(skill_path), skill_name=skill_path.name, dry_run=dry_run)
        generated.append(skill_path.name)

    return generated


# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------
def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="SKILL.md 표준 템플릿 자동 생성/검증 도구",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "--skills-dir",
        default="~/.claude/skills",
        help="스킬 디렉토리 (기본: ~/.claude/skills)",
    )
    mode = parser.add_mutually_exclusive_group()
    mode.add_argument("--verify", action="store_true", help="기존 SKILL.md 검증")
    mode.add_argument("--generate", action="store_true", help="SKILL.md 생성/갱신")
    parser.add_argument("--skill", default=None, help="특정 스킬만 처리")
    parser.add_argument("--dry-run", action="store_true", help="변경 없이 미리보기")
    return parser


def main() -> None:
    parser = build_parser()
    args = parser.parse_args()

    # 기본 동작: verify
    if not args.generate:
        args.verify = True

    try:
        if args.verify:
            result = verify_skills(skills_dir=args.skills_dir, skill_name=args.skill)
            print(json.dumps(result, ensure_ascii=False, indent=2))

        elif args.generate:
            if args.skill:
                skills_path = Path(args.skills_dir).expanduser()
                skill_path = skills_path / args.skill
                if not skill_path.exists():
                    print(f"Error: 스킬 디렉토리가 없습니다: {skill_path}", file=sys.stderr)
                    sys.exit(1)
                preview = generate_skill_md(
                    skill_dir=str(skill_path),
                    skill_name=args.skill,
                    dry_run=args.dry_run,
                )
                if args.dry_run and preview:
                    print("--- dry-run preview ---")
                    print(preview)
                else:
                    print(f"생성 완료: {skill_path / 'SKILL.md'}")
            else:
                generated = generate_all_skills(skills_dir=args.skills_dir, dry_run=args.dry_run)
                if args.dry_run:
                    print(f"dry-run: {len(generated)}개 스킬 SKILL.md 생성 예정")
                    for name in generated:
                        print(f"  - {name}")
                else:
                    print(f"{len(generated)}개 스킬 SKILL.md 생성/갱신 완료")
                    for name in generated:
                        print(f"  - {name}")

    except SkillsError as exc:
        print(f"Error: {exc}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
