#!/usr/bin/env python3
"""Comprueba UNA glosa contra el impreso sin depender del ancla del verso.

Para que. `glosas_impreso.py` localiza el verso por su transliteracion; cuando
el OCR la estropea, no hay bloque y el verso se queda sin cotejar. El 17-ago se
aplicaron cambios en 19 versos que hoy no validan bloque, y habia que poder
revisarlos: tres de los cambios de esa tanda estaban INVERTIDOS —el impreso
decia lo que el repo ya tenia— porque el ancla habia caido en otro sitio.

Como localiza la glosa sin el verso. Por dos claves del mismo verso a la vez.
Una clave suelta no vale: «te—» encabeza glosas en doscientos sitios. Pero
«te—» a menos de 400 caracteres de una clave rara del mismo verso solo puede ser
esta. Se eligen como acompañantes las claves menos frecuentes en todo el libro.

Uso:
    python3 verificar_glosa_suelta.py <fichero.md> [clave ...]
    python3 verificar_glosa_suelta.py --hoy      # todo lo cambiado hoy
"""
import json
import pathlib
import re
import subprocess
import sys

HERE = pathlib.Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
from glosas_impreso import LIBRO, REPO, pel, plano, repo_parejas  # noqa: E402

CERCA = 400


def raras(claves, texto, cuantas=3):
    """Las claves del verso que menos salen en el libro: sirven de referencia."""
    veces = [(len(re.findall(r'(?<![\w])' + re.escape(k) + r'\s*[—–]', texto)), k)
             for k in claves if len(k) > 3]
    return [k for _, k in sorted(veces)[:cuantas]]


def leer(libro, clave, acompanantes):
    """La glosa impresa de `clave`, buscada junto a alguna clave rara del verso."""
    t = plano(libro)
    for a in acompanantes:
        if a == clave:
            continue
        for ma in re.finditer(r'(?<![\w])' + re.escape(a) + r'\s*[—–]', t):
            ven = t[max(0, ma.start() - CERCA):ma.start() + CERCA]
            mk = re.search(r'(?<![\w])' + re.escape(clave) + r'\s*[—–]\s*([^;]{1,70})', ven)
            if mk:
                return mk.group(1).strip().rstrip('.'), a
    return None, None


def revisar_fichero(ruta, claves=None):
    f = REPO / ruta
    libro = next((k for k, v in LIBRO.items() if ruta.startswith(v)), None)
    if not libro or not f.is_file():
        return []
    pr = repo_parejas(f)
    t = plano(libro)
    ref = raras([c for c, _, _ in pr], t)
    fuera = []
    for c, g, crudo_k in pr:
        if claves and pel(crudo_k) not in {pel(x) for x in claves}:
            continue
        imp, con = leer(libro, c, ref)
        if imp is None:
            continue
        if pel(g) != pel(imp):
            fuera.append((crudo_k, g, imp, con))
    return fuera


def main():
    if '--hoy' in sys.argv:
        com = subprocess.run(['git', 'show', '--name-only', '--format=', 'HEAD'],
                             capture_output=True, text=True, cwd=REPO).stdout.split()
        wt = subprocess.run(['git', 'diff', '--name-only'],
                            capture_output=True, text=True, cwd=REPO).stdout.split()
        rutas = sorted({f for f in com + wt if f.endswith('.md')})
        pend = json.loads((HERE / 'sin_bloque_hoy.json').read_text(encoding='utf-8')) \
            if (HERE / 'sin_bloque_hoy.json').is_file() else rutas
        rutas = pend
    else:
        rutas = [a for a in sys.argv[1:] if not a.startswith('--') and a.endswith('.md')]
    claves = [a for a in sys.argv[1:] if not a.startswith('--') and not a.endswith('.md')]
    n = 0
    for r in rutas:
        difs = revisar_fichero(r, claves or None)
        if difs:
            print(f'\n{r.split("/")[-1]}')
            for k, v, w, con in difs:
                print(f'    {k[:20]:22} repo={v[:38]!r:42} impreso={w[:38]!r}   (junto a «{con}»)')
            n += len(difs)
    print(f'\n  glosas que difieren: {n}')
    return 0


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