"""Classify every container across golden-eye, NAS and VPS into service groups and tiers."""
import json
import re
from collections import Counter, defaultdict
from pathlib import Path

BASE = Path(__file__).resolve().parent

RULES = [
    # (group, tier, patterns) — matched against "name image"
    ("client-wp", "T0", r"vidalstudios-wp|vidalstudios-wordpress|vidalstudios-db"),
    ("client-wp", "T2", r"moody-ranch-vsk|moody-ranch-stage"),
    ("client-wp", "T3", r"rore-prod-restore|wp-plugin-dev|vidal-staging|rorecclesia"),
    ("client-static", "T0", r"vidal-redirect"),
    ("business", "T1", r"invoiceninja|docuseal|vaultwarden|gatus|gotify|hbbr|hbbs|rustdesk|tak-|traefik|cf-ddns"),
    ("media", "T2", r"plex|jellyfin|sonarr|radarr|bazarr|prowlarr|qbittorrent|rutorrent|gluetun|flaresolverr|rdt-client|deemix|tautulli|overseerr|unpackerr|cleanuparr|recyclarr|tubearchivist"),
    ("infra", "T0", r"cloudflared|portainer|filebrowser|tailnet-dns|searxng|obsidian-remote|shot-service|browser-terminal|buildkit"),
    ("product", "T2", r"urpost|seed-|dustline|aetherforge|last-flight-out|tps-workbench|academy|autonomous|ano-|temporal-"),
    ("product", "T3", r"foundry|kairos-|lfo-pg-test"),
    ("games", "T3", r"mazeforge|tinytrack|scrap|secrets-of-crimson|crimson-haven|shatterfront|ten-banners|mapforge|tiny-swords|space-formations|fpswg-map|overkill|armored-frontier|kairos-landing|nas-audit|ghostline|skybreaker|vault-tls|scrapline|homarr|blender-mcp|faster-whisper|pedantic_kepler"),
]

TARGET = {
    ("client-static", "T0"): "Pages (unlimited static requests)",
    ("client-wp", "T0"): "NAS or VPS — not the RAM-saturated laptop",
    ("business", "T1"): "NAS (already correct) or VPS",
    ("media", "T2"): "NAS (already correct — storage-bound)",
    ("infra", "T0"): "stays with whatever host it fronts",
    ("product", "T2"): "VPS for always-on, Pages/Workers for static builds",
    ("games", "T3"): "golden-eye, best-effort — or Pages if static",
    ("infra", "T1"): "stays with whatever host it fronts",
    ("unclassified", "?"): "manual decision",
}


def classify(name: str, image: str) -> tuple[str, str]:
    hay = f"{name} {image}"
    for group, tier, pat in RULES:
        if re.search(pat, hay, re.I):
            return group, tier
    return "unclassified", "?"


def load():
    rows = json.load(open(BASE / "ge.json"))
    for r in rows:
        r.setdefault("env", "golden-eye")
    nas = []
    for line in (BASE / "nas.txt").read_text().splitlines():
        parts = line.split("|")
        if len(parts) < 4:
            continue
        nas.append({"env": "NAS", "name": parts[0], "image": parts[1], "state": parts[2],
                    "status": parts[3], "project": "", "restarts": 0, "health": ""})
    vps = []
    for line in (BASE / "vps.txt").read_text().splitlines():
        parts = line.split("|")
        if len(parts) < 5:
            continue
        vps.append({"env": "VPS", "name": parts[0].lstrip("/"), "image": parts[1], "state": parts[2],
                    "restarts": int(parts[3] or 0), "health": parts[4], "project": parts[5] if len(parts) > 5 else ""})
    return rows + nas + vps


def main() -> None:
    rows = load()
    for r in rows:
        g, t = classify(r["name"], r["image"])
        r["group"], r["tier"] = g, t
        if r["state"] != "running":
            r["tier_live"], r["tier"] = t, "T4"
        else:
            r["tier_live"] = t
    json.dump(rows, open(BASE / "inventory.json", "w"), indent=1)

    print(f"total containers: {len(rows)}")
    for env in ("golden-eye", "NAS", "VPS"):
        sub = [r for r in rows if r["env"] == env]
        states = Counter(r["state"] for r in sub)
        print(f"  {env:10} {len(sub):3}  " + ", ".join(f"{k}={v}" for k, v in states.most_common()))

    print("\n by group / tier (running only):")
    live = [r for r in rows if r["state"] == "running"]
    grid = defaultdict(Counter)
    for r in live:
        grid[r["group"]][r["tier_live"]] += 1
    for g in sorted(grid):
        print(f"  {g:14} {dict(grid[g])}  total {sum(grid[g].values())}")

    print("\n running by env x group:")
    eg = defaultdict(Counter)
    for r in live:
        eg[r["env"]][r["group"]] += 1
    for env in ("golden-eye", "NAS", "VPS"):
        print(f"  {env:10} {dict(eg[env])}")

    dead = [r for r in rows if r["state"] != "running"]
    print(f"\n not running: {len(dead)}")
    print("  by group:", dict(Counter(r["group"] for r in dead)))
    print("  by env:  ", dict(Counter(r["env"] for r in dead)))

    un = [r for r in rows if r["group"] == "unclassified"]
    if un:
        print("\n UNCLASSIFIED:", [(r["env"], r["name"], r["image"][:30]) for r in un])


if __name__ == "__main__":
    main()
