#!/usr/bin/env python3
"""Crea un inventario CSV e Markdown delle dipendenze senza valori segreti."""

from __future__ import annotations

import argparse
import csv
import json
import sys
from pathlib import Path
from typing import Any, Iterable
from urllib.parse import urlparse


FIELDS = ["workflow", "version", "owner", "category", "name", "type", "notes"]


def safe_webhook(value: str) -> str:
    parsed = urlparse(value)
    return parsed.hostname or "webhook-configurato"


def rows_for_manifest(data: dict[str, Any], source: str) -> list[dict[str, str]]:
    workflow = str(data.get("id") or source)
    base = {
        "workflow": workflow,
        "version": str(data.get("version", "")),
        "owner": str(data.get("owner", "")),
    }
    rows: list[dict[str, str]] = []

    def add(category: str, name: str, item_type: str = "", notes: str = "") -> None:
        rows.append({**base, "category": category, "name": name, "type": item_type, "notes": notes})

    for item in data.get("dependencies", []):
        if not isinstance(item, dict):
            continue
        notes = "credenziale logica dichiarata" if item.get("credential") else ""
        add("dipendenza", str(item.get("name", "senza-nome")), str(item.get("type", "")), notes)
    for item in data.get("variables", []):
        if isinstance(item, dict) and item.get("name"):
            add("variabile", str(item["name"]), "configurazione", "obbligatoria" if item.get("required") else "facoltativa")
        elif isinstance(item, str):
            add("variabile", item, "configurazione")
    for model in data.get("models", []):
        if isinstance(model, str):
            add("modello", model, "AI")
        elif isinstance(model, dict) and model.get("name"):
            add("modello", str(model["name"]), str(model.get("provider", "AI")))
    for webhook in data.get("webhooks", []):
        if isinstance(webhook, str):
            add("webhook", safe_webhook(webhook), "endpoint", "URL ridotto al solo host")
        elif isinstance(webhook, dict):
            name = str(webhook.get("name") or safe_webhook(str(webhook.get("url", ""))))
            add("webhook", name, "endpoint", "valore non esportato")
    for permission in data.get("permissions", []):
        if isinstance(permission, str):
            add("permesso", permission, "accesso")
        elif isinstance(permission, dict) and permission.get("name"):
            add("permesso", str(permission["name"]), str(permission.get("level", "accesso")))
    return rows


def to_markdown(rows: Iterable[dict[str, str]]) -> str:
    lines = [
        "# Inventario dipendenze workflow",
        "",
        "| Workflow | Versione | Categoria | Nome | Tipo | Note |",
        "| --- | --- | --- | --- | --- | --- |",
    ]
    for row in rows:
        values = [row[key].replace("|", "\\|") for key in ("workflow", "version", "category", "name", "type", "notes")]
        lines.append("| " + " | ".join(values) + " |")
    lines.extend(["", "I valori delle credenziali e gli URL completi non sono esportati."])
    return "\n".join(lines) + "\n"


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("manifests", type=Path, nargs="+")
    parser.add_argument("--output-dir", type=Path, required=True)
    args = parser.parse_args()
    rows: list[dict[str, str]] = []
    try:
        for path in args.manifests:
            data = json.loads(path.read_text(encoding="utf-8"))
            if not isinstance(data, dict):
                raise ValueError(f"{path}: la radice deve essere un oggetto")
            rows.extend(rows_for_manifest(data, path.name))
    except (OSError, json.JSONDecodeError, ValueError) as exc:
        print(f"Impossibile creare l'inventario: {exc}", file=sys.stderr)
        return 2

    rows.sort(key=lambda row: (row["workflow"], row["category"], row["name"]))
    args.output_dir.mkdir(parents=True, exist_ok=True)
    csv_path = args.output_dir / "dependencies.csv"
    md_path = args.output_dir / "dependencies.md"
    with csv_path.open("w", encoding="utf-8", newline="") as handle:
        writer = csv.DictWriter(handle, fieldnames=FIELDS)
        writer.writeheader()
        writer.writerows(rows)
    md_path.write_text(to_markdown(rows), encoding="utf-8")
    print(f"Creati {csv_path} e {md_path} ({len(rows)} righe).")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
