"""Synchronizacja skilli z Claude Code do Codexa (promptowy.com).

Kopiuje foldery skilli (każdy z plikiem SKILL.md) z Claude Code do folderu,
z którego Codex czyta skille użytkownika. Domyślnie:
    źródło: ~/.claude/skills
    cel:    ~/.agents/skills

Skrypt prowadzi rejestr skopiowanych skilli (.synchronizuj-skille.json w folderze
docelowym). Przy kolejnym uruchomieniu nadpisuje tylko je, a skille założone
w Codexie ręcznie zostawia w spokoju. Sprawdza też, czy SKILL.md ma pola
name i description, bez których Codex skilla nie wczyta.

Użycie:
    python synchronizuj-skille.py                    # domyślne foldery
    python synchronizuj-skille.py --na-sucho         # tylko pokaż, co by zrobił
    python synchronizuj-skille.py --zrodlo D:/skille --zrodlo ~/.claude/skills
    python synchronizuj-skille.py --cel ./projekt/.agents/skills

Wymaga Pythona 3.8+, bez dodatkowych bibliotek. Działa na Windows, macOS i Linux.
Po synchronizacji uruchom Codexa ponownie, żeby wczytał skille.
"""
import argparse
import json
import re
import shutil
import sys
from pathlib import Path

REJESTR_PLIK = ".synchronizuj-skille.json"
POMIJAJ = shutil.ignore_patterns("__pycache__", ".git", "node_modules", ".DS_Store")


def sciezka(tekst):
    return Path(tekst).expanduser().resolve()


def sprawdz_frontmatter(skill_md):
    """Zwraca listę braków w nagłówku SKILL.md (pusta lista = w porządku)."""
    tekst = skill_md.read_text(encoding="utf-8", errors="replace")
    m = re.match(r"^---\s*\n(.*?)\n---", tekst, re.S)
    if not m:
        return ["brak nagłówka --- na początku pliku"]
    naglowek = m.group(1)
    return [f"brak pola {pole}" for pole in ("name", "description")
            if not re.search(rf"^{pole}\s*:\s*\S", naglowek, re.M)]


def main():
    p = argparse.ArgumentParser(description="Kopiuje skille z Claude Code do Codexa.")
    p.add_argument("--zrodlo", action="append", type=sciezka,
                   help="folder ze skillami (można podać kilka razy); domyślnie ~/.claude/skills")
    p.add_argument("--cel", type=sciezka, default=sciezka("~/.agents/skills"),
                   help="folder skilli Codexa; domyślnie ~/.agents/skills")
    p.add_argument("--na-sucho", action="store_true", help="nic nie zapisuj, tylko pokaż plan")
    a = p.parse_args()
    zrodla = a.zrodlo or [sciezka("~/.claude/skills")]

    rejestr_plik = a.cel / REJESTR_PLIK
    nasze = set()
    if rejestr_plik.exists():
        nasze = set(json.loads(rejestr_plik.read_text(encoding="utf-8")))

    skopiowane, pominiete, ostrzezenia = [], [], []
    for zrodlo in zrodla:
        if not zrodlo.is_dir():
            print(f"BRAK     {zrodlo} - folder nie istnieje, pomijam")
            continue
        for skill in sorted(x for x in zrodlo.iterdir() if (x / "SKILL.md").is_file()):
            cel = a.cel / skill.name
            if skill.name in skopiowane:
                pominiete.append(skill.name)
                print(f"DUBEL    {skill.name} - już skopiowany z wcześniejszego źródła, pomijam")
                continue
            if cel.exists() and skill.name not in nasze:
                pominiete.append(skill.name)
                print(f"POMIJAM  {skill.name} - w celu jest skill o tej nazwie, którego nie kopiowałem")
                continue
            for brak in sprawdz_frontmatter(skill / "SKILL.md"):
                ostrzezenia.append(f"{skill.name}: {brak}")
            if not a.na_sucho:
                a.cel.mkdir(parents=True, exist_ok=True)
                if cel.exists():
                    shutil.rmtree(cel)
                shutil.copytree(skill, cel, ignore=POMIJAJ)
            skopiowane.append(skill.name)
            print(f"{'PLAN' if a.na_sucho else 'OK'}{' ' * (9 - len('PLAN' if a.na_sucho else 'OK'))}{skill.name}  <- {zrodlo}")

    if not a.na_sucho and skopiowane:
        rejestr_plik.write_text(json.dumps(sorted(nasze | set(skopiowane)), ensure_ascii=False, indent=1),
                                encoding="utf-8")

    print(f"\n{'Do skopiowania' if a.na_sucho else 'Skopiowane'}: {len(skopiowane)}, pominięte: {len(pominiete)}, cel: {a.cel}")
    for o in ostrzezenia:
        print(f"UWAGA    {o} - Codex wymaga pól name i description w nagłówku SKILL.md")
    if skopiowane and not a.na_sucho:
        print("Uruchom Codexa ponownie, żeby wczytał skille.")
    return 1 if ostrzezenia else 0


if __name__ == "__main__":
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8")
    sys.exit(main())
