"""Scan .claude/skills/ and extract metadata from SKILL.md files."""

from __future__ import annotations

import re
import sys
from pathlib import Path
from typing import Any


def find_skills_dir(project_dir: Path | None = None) -> Path:
    """Return .claude/skills/ directory for the given or current project."""
    base = project_dir or Path.cwd()
    return base / ".claude" / "skills"


def _read_text_safe(path: Path) -> str | None:
    """Read a text file, returning *None* on encoding or OS errors."""
    try:
        content = path.read_text(encoding="utf-8-sig")  # handles BOM
        return content
    except (OSError, UnicodeDecodeError):
        print(
            f"Warning: could not read {path} (encoding or permission issue)",
            file=sys.stderr,
        )
        return None


def parse_frontmatter(content: str) -> dict[str, Any]:
    """Extract YAML frontmatter from a markdown file.

    Handles single-line ``key: value`` pairs and multi-line values using
    the YAML ``|`` block scalar indicator.  Does not depend on pyyaml.
    """
    # Strip BOM if present (belt-and-suspenders; utf-8-sig handles it at read)
    content = content.lstrip("\ufeff")
    match = re.match(r"^---\s*\n(.*?)\n---", content, re.DOTALL)
    if not match:
        return {}

    result: dict[str, Any] = {}
    current_key: str | None = None
    current_lines: list[str] = []

    for line in match.group(1).split("\n"):
        # Top-level key: value
        top_match = re.match(r"^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)", line)
        if top_match:
            # Flush previous multi-line key
            if current_key is not None:
                result[current_key] = "\n".join(current_lines).strip()
            key = top_match.group(1)
            current_key = key
            value = top_match.group(2).strip()
            if value == "|" or value == ">":
                current_lines = []
            else:
                result[key] = value
                current_key = None
                current_lines = []
        elif current_key is not None:
            # Continuation line for a multi-line value
            current_lines.append(line.strip())

    # Flush last multi-line key
    if current_key is not None:
        result[current_key] = "\n".join(current_lines).strip()

    return result


def scan_skills(project_dir: Path | None = None) -> list[dict[str, Any]]:
    """Scan all skills and return metadata list.

    Each entry contains ``name``, ``description``, ``version``, and ``path``.
    Silently skips files that cannot be read.
    """
    skills_dir = find_skills_dir(project_dir)
    results: list[dict[str, Any]] = []
    if not skills_dir.is_dir():
        return results

    for skill_dir in sorted(skills_dir.iterdir()):
        if not skill_dir.is_dir():
            continue
        skill_file = skill_dir / "SKILL.md"
        if not skill_file.is_file():
            continue
        content = _read_text_safe(skill_file)
        if content is None:
            continue
        meta = parse_frontmatter(content)
        results.append(
            {
                "name": meta.get("name", skill_dir.name),
                "description": meta.get("description", ""),
                "version": meta.get("version", ""),
                "path": str(skill_dir),
            }
        )

    return results
