# -*- coding: utf-8 -*-
"""Itérations et annexes : « refais la section chiffres », « crée la page
Exposants », « convertis en Elementor » sont des messages de plus dans le
même dialogue. Vérifie aussi le verrou du worker."""

import os, shutil, subprocess, sys, tempfile, time

BASE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE); sys.path.insert(0, os.path.join(BASE, "tests"))
_BAC = tempfile.mkdtemp(prefix="plateforme-relance-")
os.environ["PLATEFORME_PROJETS"] = os.path.join(_BAC, "projets")
os.environ["PLATEFORME_BASE"] = os.path.join(_BAC, "projets.db")

import claude, projets, prompt, worker
import faux_client as fc

OK = [0, 0]
def v(c, l):
    OK[0 if c else 1] += 1
    print("  %s %s" % ("ok  " if c else "ECHEC", l))

projets.initialiser()
pid = projets.creer("Itérations")
prompt.preparer(pid, {"client": "Test", "pages": "l'accueil"})

# --- Première génération ---------------------------------------------------
faux = fc.FauxClient([
    fc.Reponse([fc.appel("a1", "ecrire_fichier",
                         {"chemin": "index.html", "contenu": "<p>chiffres v1</p>"})], "tool_use"),
    fc.Reponse([fc.appel("a2", "terminer", {"resume": "v1 livrée"})], "tool_use"),
])
claude._client = lambda: faux
worker.main()
site = projets.dossier_site(pid)
v(projets.lire(pid)["etat"] == projets.TERMINE, "première génération terminée")
jointes = len(projets.lire_conversation(pid)["messages"])

# --- Itération 1 : refaire une section -------------------------------------
claude.relancer(pid, "Refais la section chiffres, plus aérée.")
p = projets.lire(pid)
v(p["etat"] == projets.EN_ATTENTE, "la consigne remet le projet en file")
conv = projets.lire_conversation(pid)
v(len(conv["messages"]) == jointes + 1, "un seul message ajouté, le contexte est conservé")
v(conv["messages"][0]["content"][0]["type"] in ("text", "document", "image"),
  "le brief initial est toujours en tête (cache préservé)")

faux2 = fc.FauxClient([
    fc.Reponse([fc.appel("b1", "lire_fichier", {"chemin": "index.html"})], "tool_use"),
    fc.Reponse([fc.appel("b2", "ecrire_fichier",
                         {"chemin": "index.html", "contenu": "<p>chiffres v2</p>"})], "tool_use"),
    fc.Reponse([fc.appel("b3", "terminer", {"resume": "section refaite"})], "tool_use"),
])
claude._client = lambda: faux2
worker.main()
v(open(os.path.join(site, "index.html")).read() == "<p>chiffres v2</p>", "section régénérée")
v(projets.lire(pid)["etat"] == projets.TERMINE, "itération terminée")

# le premier message envoyé à l'API doit contenir tout l'historique
premiere = faux2.requetes[0]
v(len(premiere["messages"]) >= jointes + 1,
  "l'historique complet repart à l'API (%d messages)" % len(premiere["messages"]))
v(any("chiffres" in str(m) for m in premiere["messages"]), "le travail précédent est dans le contexte")

# --- Itération 2 : annexe C, conversion Elementor --------------------------
claude.relancer(pid, "Convertis chaque page, l'en-tête et le pied de page en "
                     "gabarits JSON importables dans Elementor, en widgets natifs.")
faux3 = fc.FauxClient([
    fc.Reponse([fc.appel("c1", "ecrire_fichier",
                         {"chemin": "tools/build_elementor.py",
                          "contenu": "# generateur\nprint('ok')\n"})], "tool_use"),
    fc.Reponse([fc.appel("c2", "terminer", {"resume": "gabarits Elementor produits"})], "tool_use"),
])
claude._client = lambda: faux3
worker.main()
v(os.path.isfile(os.path.join(site, "tools/build_elementor.py")), "annexe Elementor : script écrit")
p = projets.lire(pid)
v(p["tours"] == 7, "7 tours cumulés sur les trois passes (vu : %d)" % p["tours"])
v("Elementor" in (p["resume"] or ""), "dernier résumé enregistré")

consignes = [j["detail"] for j in projets.journal(pid) if j["evenement"] == "consigne"]
v(len(consignes) == 2, "les deux consignes sont tracées")

# --- Verrou du worker ------------------------------------------------------
print("\n-- verrou : deux workers simultanés")
code = ("import fcntl,os,sys,time\n"
        "sys.path.insert(0,%r)\n"
        "import worker\n"
        "v=worker._prendre_verrou()\n"
        "print('PRIS' if v else 'REFUSE')\n"
        "time.sleep(2)\n" % BASE)
un = subprocess.Popen([sys.executable, "-c", code], stdout=subprocess.PIPE, text=True,
                      env={**os.environ, "PYTHONPATH": BASE})
time.sleep(0.7)
deux = subprocess.run([sys.executable, "-c", code.replace("time.sleep(2)", "pass")],
                      capture_output=True, text=True, env={**os.environ, "PYTHONPATH": BASE})
sortie_un = un.communicate()[0].strip()
v(sortie_un == "PRIS", "le premier worker prend le verrou")
v(deux.stdout.strip() == "REFUSE", "le second ressort immédiatement (vu : %r)" % deux.stdout.strip())

print("\n%d ok, %d échecs" % (OK[0], OK[1]))
shutil.rmtree(_BAC, ignore_errors=True)
sys.exit(1 if OK[1] else 0)
