#!/usr/bin/env python3
"""Pulsar una accion PREGUNTA lo que falta y la hace.

    ./venv/bin/python pruebas/prueba_dialogo.py

Antes, pulsar en "sabe hacer" recitaba la frase que dispara la accion. Eso es un
manual de instrucciones, y uno pulsa justo porque no quiere leerse el manual.

Lo que se comprueba, por orden de importancia:

  1. que lo destructivo NO se dispare de un clic
  2. que lo destructivo CON argumento pregunte las DOS cosas
  3. que un "no" cancele de verdad
  4. que la pregunta caduque, para que una frase suelta media conversacion
     despues no se tome por la respuesta
"""
import os
import sys
import time

AQUI = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, AQUI)

from cara.panel import Panel                                   # noqa: E402
from manos import Manos                                        # noqa: E402
from manos.preguntar import pregunta_por, es_si                # noqa: E402

fallos = []


def afirma(condicion, queja):
    print(f"  {'OK ' if condicion else 'MAL'} {queja}")
    if not condicion:
        fallos.append(queja)


class CaraFalsa:
    conectados = 1
    def __init__(self): self.m = []
    def manda(self, t, d): self.m.append((t, d))


class BocaMuda:
    voz = "davefx"
    def __init__(self): self.dicho = []
    def di(self, t): self.dicho.append(t); return True
    def di_si_libre(self, t): return self.di(t)
    def disponibles(self): return ["davefx"]


def nuevo():
    cara, boca = CaraFalsa(), BocaMuda()
    return Panel(cara, boca, Manos(), candado=False), boca


def main() -> int:
    print("\n  las preguntas salen del catalogo")
    manos = Manos()
    conArg = [a for a in manos.catalogo.acciones if a.captura]
    genericas = [a for a in conArg if pregunta_por(a) == "¿El que, señor?"]
    afirma(len(conArg) >= 30, f"{len(conArg)} acciones piden argumento")
    afirma(len(genericas) <= 10,
           f"solo {len(genericas)} caen en la pregunta generica, de {len(conArg)}")
    afirma(all(pregunta_por(a).endswith("señor?") for a in conArg),
           "todas preguntan en el registro de la casa")
    afirma("cierra" not in [pregunta_por(a).split()[0].strip("¿").lower()
                            for a in conArg],
           "y ninguna empieza por el verbo de la orden")

    print("\n  con argumento: pregunta y ejecuta con lo que le digas")
    p, boca = nuevo()
    p.pulsado("accion", "explica:buscar_fichero"); time.sleep(0.2)
    afirma(bool(p.esperando()), "se queda esperando respuesta")
    afirma(any("fichero" in d for d in boca.dicho), f"pregunta cual: {boca.dicho}")
    p.responde("informes"); time.sleep(1.5)
    tareas = [t.titulo for t in p.tareas.todas()]
    afirma(any("informes" in t for t in tareas), f"lo ejecuta con el argumento: {tareas}")
    afirma(not p.esperando(), "y deja de esperar")
    p.para()

    print("\n  lo destructivo NO se dispara de un clic")
    p, boca = nuevo()
    p.pulsado("accion", "explica:ff_firefox_cerrar"); time.sleep(0.3)
    afirma(not p.tareas.todas(), "no ha lanzado nada al pulsar")
    afirma(bool(p.esperando()), "esta esperando confirmacion")
    p.responde("no"); time.sleep(0.4)
    afirma(not p.tareas.todas(), "y con un 'no' sigue sin lanzar nada")
    p.para()

    print("\n  destructivo CON argumento: las dos preguntas")
    p, boca = nuevo()
    p.pulsado("accion", "explica:proceso_matar"); time.sleep(0.2)
    afirma(bool(p.esperando()), "pregunta el argumento")
    p.responde("firefox"); time.sleep(0.3)
    afirma(bool(p.esperando()),
           "y DESPUES pide confirmacion, no ejecuta directo")
    afirma(any("firefox" in d for d in boca.dicho),
           "la confirmacion dice sobre que va, no un cheque en blanco")
    p.responde("no"); time.sleep(0.4)
    afirma(not p.tareas.todas(), "un 'no' lo cancela")
    p.para()

    print("\n  lo que no pregunta nada, se hace")
    p, boca = nuevo()
    p.pulsado("accion", "explica:disco_libre"); time.sleep(1.5)
    afirma(bool(p.tareas.todas()), "una accion sin argumento ni riesgo se ejecuta")
    afirma(not p.esperando(), "sin preguntar nada")
    p.para()

    print("\n  la pregunta caduca")
    p, boca = nuevo()
    p.ESPERA_S = 0.5
    p.pulsado("accion", "explica:buscar_fichero"); time.sleep(0.2)
    afirma(bool(p.esperando()), "recien preguntada, espera")
    time.sleep(0.8)
    afirma(not p.esperando(),
           "pasado el plazo la olvida: una frase suelta media conversacion "
           "despues no puede tomarse por la respuesta")
    p.para()

    print("\n  el si y el no, como los dice la gente")
    for t, esperado in [("si", True), ("Sí.", True), ("vale", True),
                        ("claro que si", True), ("no", False), ("dejalo", False),
                        ("no, mejor no", False), ("informes", None),
                        ("el fichero de agosto", None)]:
        afirma(es_si(t) is esperado, f"{t!r} -> {es_si(t)}")

    print(f"\n  {'todo en orden' if not fallos else str(len(fallos)) + ' fallan'}\n")
    return 1 if fallos else 0


if __name__ == "__main__":
    sys.exit(main())
