#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
À lancer en SSH sur l'hébergement, avant toute chose :

    ./venv/bin/python verifier_installation.py

Contrôle les quatre points qui peuvent réellement bloquer sur un mutualisé,
puis, si une clé API est en place, fait un appel réel de quelques jetons pour
vérifier de bout en bout.
"""

import os
import shutil
import subprocess
import sys

BILAN = []


def point(ok, libelle, remede=None):
    BILAN.append(ok)
    print("  %s %s" % ("OK    " if ok else "BLOQUÉ", libelle))
    if not ok and remede:
        print("         → %s" % remede)


print("== 1. Python ==")
version = sys.version_info
point(version >= (3, 9), "Python %d.%d.%d" % version[:3],
      "Il faut Python 3.9 ou plus. Sur cPanel : Setup Python App.")

print("\n== 2. Dépendances ==")
for module, paquet in [("anthropic", "anthropic"), ("flask", "flask")]:
    try:
        __import__(module)
        point(True, "%s installé" % module)
    except ImportError:
        point(False, "%s absent" % module, "pip install %s" % paquet)

print("\n== 3. Écriture sur disque ==")
racine = os.path.dirname(os.path.abspath(__file__))
try:
    essai = os.path.join(racine, ".essai-ecriture")
    with open(essai, "w") as f:
        f.write("ok")
    os.remove(essai)
    point(True, "le dossier de la plateforme est inscriptible")
except OSError as e:
    point(False, "écriture impossible : %s" % e, "Vérifiez les droits du dossier.")

libre = shutil.disk_usage(racine).free // (1024 * 1024)
point(libre > 500, "espace libre : %d Mo" % libre,
      "Comptez ~50 Mo par projet. Faites du ménage ou augmentez le quota.")

print("\n== 4. Cron ==")
try:
    r = subprocess.run(["crontab", "-l"], capture_output=True, text=True, timeout=10)
    dispo = r.returncode in (0, 1)
    point(dispo, "commande crontab disponible")
    if dispo and "worker.py" in (r.stdout or ""):
        point(True, "la ligne de cron du worker est déjà posée")
    elif dispo:
        print("         → à ajouter (crontab -e) :")
        print("           * * * * * cd %s && %s worker.py >> worker.log 2>&1"
              % (racine, sys.executable))
except (OSError, subprocess.SubprocessError) as e:
    point(False, "crontab inaccessible : %s" % e,
          "Sur cPanel, passez par l'interface « Tâches Cron ».")

print("\n== 5. Sortie HTTPS vers l'API ==")
# C'est le seul point qui peut condamner l'hébergement : certains mutualisés
# filtrent les connexions sortantes.
try:
    import urllib.error
    import urllib.request
    requete = urllib.request.Request(
        "https://api.anthropic.com/v1/messages", method="POST",
        data=b"{}", headers={"content-type": "application/json"})
    try:
        urllib.request.urlopen(requete, timeout=20)
        point(True, "api.anthropic.com joignable")
    except urllib.error.HTTPError as e:
        # 401 = on a bien atteint l'API, elle réclame une clé. C'est le
        # résultat attendu et c'est une bonne nouvelle.
        point(e.code in (400, 401, 403), "api.anthropic.com joignable (HTTP %d)" % e.code,
              None if e.code in (400, 401, 403) else
              "Réponse inattendue : un filtrage sortant est possible.")
    except urllib.error.URLError as e:
        point(False, "api.anthropic.com injoignable : %s" % e.reason,
              "Connexions sortantes filtrées. Demandez l'ouverture du port 443 "
              "vers api.anthropic.com au support de l'hébergeur.")
except Exception as e:
    point(False, "test réseau impossible : %s" % e)

print("\n== 6. Clé API ==")
sys.path.insert(0, racine)
try:
    import config  # charge .env
except ImportError:
    pass
cle = os.environ.get("ANTHROPIC_API_KEY", "")
if not cle:
    point(False, "ANTHROPIC_API_KEY absente",
          "Créez un compte sur console.anthropic.com, générez une clé, posez-la "
          "dans le fichier .env : ANTHROPIC_API_KEY=sk-ant-...")
else:
    point(True, "clé présente (%s…%s)" % (cle[:11], cle[-4:]))
    print("\n== 7. Appel réel ==")
    try:
        import anthropic
        client = anthropic.Anthropic()
        reponse = client.messages.create(
            model=config.MODELE, max_tokens=16,
            messages=[{"role": "user", "content": "Réponds exactement : prêt"}],
        )
        texte = "".join(b.text for b in reponse.content if b.type == "text").strip()
        point(bool(texte), "%s a répondu : %r" % (config.MODELE, texte[:40]))
        print("         jetons : %d en entrée, %d en sortie"
              % (reponse.usage.input_tokens, reponse.usage.output_tokens))
    except Exception as e:
        point(False, "appel refusé : %s: %s" % (type(e).__name__, e),
              "Clé invalide, crédits épuisés, ou modèle indisponible sur ce compte.")

echecs = BILAN.count(False)
print("\n%s" % ("=" * 60))
if echecs:
    print("%d point(s) à régler avant de lancer la plateforme." % echecs)
else:
    print("Tout est en place. Lancez le worker : ./venv/bin/python worker.py")
sys.exit(1 if echecs else 0)
