#!/usr/bin/env python3
# Genera, con la voz CLONADA (XTTS-v2), las frases fijas que JARVIS repite:
# los acuses de las acciones y las respuestas de plantilla del panel. Cada WAV
# se guarda en cache_voz/ con nombre = sha1(texto normalizado), que es la misma
# clave que usa el wrapper jarvis-voz.sh para servirlas al instante.
#
# Corre en el host (venv clonador-venv), en GPU, sin prisa: es trabajo de una
# sola vez. En uso, el wrapper solo copia el WAV -> latencia cero, GPU libre.
#
#   python generar_cache_voz.py [cuda|cpu]
import os, sys, re, json, glob, hashlib, time

DISPOSITIVO = sys.argv[1] if len(sys.argv) > 1 else "cuda"
BASE = os.path.dirname(os.path.abspath(__file__))
# La voz (referencia, condicionado y parametros) vive en clonador.py: tenerla
# aqui y en calienta_cache.py significaba dos copias que se desincronizan.
sys.path.insert(0, BASE)
from clonador import Clonador, clave
CACHE = os.path.join(BASE, "cache_voz")
CATALOGO = os.path.expanduser(
    "~/COFRE/CODERS/JARVIS/newelle/data/acciones/acciones.json")
os.makedirs(CACHE, exist_ok=True)

os.environ.setdefault("COQUI_TOS_AGREED", "1")


def frases_fijas():
    """Acuses del catalogo + respuestas de plantilla del panel."""
    fijas = set()
    try:
        with open(CATALOGO, encoding="utf-8") as f:
            cat = json.load(f)
        for a in cat.get("acciones", cat if isinstance(cat, list) else []):
            ac = a.get("acuse")
            if ac:
                fijas.add(ac)
    except Exception as e:
        print(f"aviso: no pude leer el catalogo ({e}); sigo con las fijas")
    # las de plantilla del panel que no dependen de argumento
    fijas.update({
        "Buenas noches, señor. Todo está listo.",
        "Lo busco dentro, señor.",
        "A la orden, señor.",
        "Hecho, señor.",
        "No he encontrado nada, señor.",
        "¿Cuál de estos, señor?",
    })
    return sorted(fijas)


def main():
    frases = frases_fijas()
    print(f"{len(frases)} frases fijas a generar en {DISPOSITIVO}", flush=True)

    t0 = time.time()
    voz = Clonador(DISPOSITIVO)
    print(f"modelo cargado en {time.time()-t0:.1f} s "
          f"(referencia: {os.path.basename(voz.referencia)})", flush=True)

    hechas = saltadas = 0
    for i, frase in enumerate(frases, 1):
        dst = os.path.join(CACHE, clave(frase) + ".wav")
        if os.path.exists(dst):
            saltadas += 1
            continue
        t0 = time.time()
        voz.genera(frase, dst)
        print(f"  [{i}/{len(frases)}] {time.time()-t0:4.1f}s  {frase[:50]}",
              flush=True)
        hechas += 1
    print(f"listo: {hechas} generadas, {saltadas} ya estaban. cache -> {CACHE}",
          flush=True)


if __name__ == "__main__":
    main()
