"""Ajoute colonne environnement sur servers et importe depuis CSV iTop.

Stocke les 7 valeurs iTop verbatim: Développement, Intégration, Pré-Prod,
Production, Recette, Test, Formation.

Usage:
    python tools/import_environnement.py <csv1> [<csv2> ...] [--dry-run]
"""
import os
import csv
import argparse
from sqlalchemy import create_engine, text

DATABASE_URL = os.getenv("DATABASE_URL_DEMO") or os.getenv("DATABASE_URL") \
    or "postgresql://patchcenter:PatchCenter2026!@localhost:5432/patchcenter_demo"

ITOP_ENVS = [
    "Développement", "Intégration", "Pré-Prod",
    "Production", "Recette", "Test", "Formation",
]

# Aliases courants -> valeur iTop canonique
ENV_ALIASES = {
    "developpement": "Développement",
    "dev": "Développement",
    "integration": "Intégration",
    "int": "Intégration",
    "preprod": "Pré-Prod",
    "pre-prod": "Pré-Prod",
    "pre prod": "Pré-Prod",
    "prod": "Production",
    "production": "Production",
    "recette": "Recette",
    "rec": "Recette",
    "test": "Test",
    "tests": "Test",
    "formation": "Formation",
}


def norm_env(raw):
    if not raw:
        return None
    s = raw.strip()
    if not s or s in ("-", "(null)", "workgroup"):
        return None
    if s in ITOP_ENVS:
        return s
    return ENV_ALIASES.get(s.lower())


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("csv_paths", nargs="+")
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()

    engine = create_engine(DATABASE_URL)
    print(f"[INFO] DB: {DATABASE_URL.split('@')[-1]}")
    conn = engine.connect().execution_options(isolation_level="AUTOCOMMIT")

    # 1. Ajoute colonne + CHECK (idempotent, toujours execute y compris dry-run)
    print("[INFO] Ajoute colonne environnement...")
    conn.execute(text("ALTER TABLE servers ADD COLUMN IF NOT EXISTS environnement varchar(20)"))
    conn.execute(text("ALTER TABLE servers DROP CONSTRAINT IF EXISTS servers_environnement_check"))
    allowed_sql = ", ".join(f"'{v}'" for v in ITOP_ENVS)
    conn.execute(text(
        f"ALTER TABLE servers ADD CONSTRAINT servers_environnement_check "
        f"CHECK (environnement IN ({allowed_sql}) OR environnement IS NULL)"
    ))
    print(f"[INFO] Envs iTop autorises: {ITOP_ENVS}")

    # 2. Relecture CSV -> update
    updated = 0
    unchanged = 0
    not_found = 0
    unknown = set()

    for csv_path in args.csv_paths:
        print(f"\n[INFO] Lecture {csv_path}")
        with open(csv_path, "r", encoding="utf-8-sig", newline="") as f:
            sample = f.read(4096)
            f.seek(0)
            delim = ";" if sample.count(";") > sample.count(",") else ","
            reader = csv.DictReader(f, delimiter=delim)
            rows = list(reader)
        print(f"[INFO] {len(rows)} lignes (delim={delim!r})")

        for r in rows:
            hostname = (r.get("Nom") or r.get("Hostname") or "").strip()
            if not hostname or not any(c.isalpha() for c in hostname):
                continue
            raw = (r.get("Environnement") or r.get("Environment") or "").strip()
            new_env = norm_env(raw)
            if raw and new_env is None and raw not in ("-", "(null)", "workgroup", ""):
                unknown.add(raw)
                continue
            if new_env is None:
                continue
            srv = conn.execute(text("SELECT id, environnement FROM servers WHERE hostname=:h"),
                               {"h": hostname}).fetchone()
            if not srv:
                not_found += 1
                continue
            if srv.environnement == new_env:
                unchanged += 1
                continue
            if args.dry_run:
                print(f"  DRY: {hostname}  {srv.environnement} -> {new_env}")
            else:
                conn.execute(text("UPDATE servers SET environnement=:e WHERE id=:sid"),
                             {"e": new_env, "sid": srv.id})
            updated += 1

    conn.close()
    print(f"\n[DONE] Maj: {updated} | Inchanges: {unchanged} | Hors base: {not_found}")
    if unknown:
        print(f"[WARN] Valeurs non mappees: {unknown}")


if __name__ == "__main__":
    main()
