#!/usr/bin/env python3
"""Decide quien tiene razon en cada divergencia repo/D1, leyendo el escaneo.

Entra `paridad_clasificada.json`. Para cada palabra que difiere se localiza el
sitio en el .md del repo, se toma el contexto izquierdo y se busca en el OCR del
libro. La forma que aparezca acompañada de ese contexto es la del papel.

Por que el contexto en cascada. La aparicion puede abrir el significado, y ahi
el OCR mete la palabra «purport» entre la traduccion y el texto, asi que el
contexto de cinco palabras del repo no sale seguido. Se prueban 5, 4, 3 y 2.
Con menos de dos no se decide: cualquier par de palabras sale cien veces.

Por que no vale el conteo sobre el libro entero. Con palabras cortas engaña:
«or» sale miles de veces y no dice nada de `cc/adi/7/73`.

Uso:
    python3 arbitrar_paridad.py
    python3 arbitrar_paridad.py --clase "palabras cambiadas"
"""
import json
import pathlib
import re
import sys

HERE = pathlib.Path(__file__).resolve().parent
REPO = pathlib.Path('/Users/jaganat/git_projects/vedabase-original')
sys.path.insert(0, str(HERE))
from arbitrar_deriva import texto_escaneo, norm  # noqa: E402


def contexto(texto, palabra):
    """Cada aparicion de `palabra` en el .md, con sus cinco palabras previas."""
    fuera = []
    for m in re.finditer(r'(?<![\wĀ-ỿ])' + re.escape(palabra)
                         + r'(?![\wĀ-ỿ])', texto):
        izq = texto[:m.start()].split()[-5:]
        fuera.append((' '.join(izq), m.start()))
    return fuera


def lee(esc, izq, a, b):
    """Cual de las dos formas acompaña a ese contexto en el impreso."""
    pal = izq.split()
    for k in (5, 4, 3, 2):
        if len(pal) < k:
            continue
        ctx = norm(' '.join(pal[-k:]))
        if len(ctx.split()) < 2:
            continue
        na = esc.count(f'{ctx} {norm(a)}')
        nb = esc.count(f'{ctx} {norm(b)}')
        if na and not nb:
            return 'repo'
        if nb and not na:
            return 'd1'
    return None


def main():
    solo = sys.argv[sys.argv.index('--clase') + 1] if '--clase' in sys.argv else None
    grupos = json.loads((HERE / 'paridad_clasificada.json').read_text(encoding='utf-8'))
    casos = grupos.get(solo, []) if solo else grupos.get('palabras cambiadas', [])
    res = {'D1 equivocado': [], 'repo equivocado': [], 'sin decidir': []}
    for x in casos:
        libro = x['ref'].split('/')[0]
        esc = texto_escaneo(libro)
        t = (REPO / x['file']).read_text(encoding='utf-8')
        # emparejar cada palabra del repo con la de D1 que ocupa su sitio
        for pr, pd in zip(x['solo_repo'], x['solo_d1']):
            if norm(pr) == norm(pd):
                continue
            veredicto = None
            for izq, _ in contexto(t, pr):
                veredicto = lee(esc, izq, pr, pd)
                if veredicto:
                    break
            fila = {'ref': x['ref'], 'file': x['file'], 'repo': pr, 'd1': pd,
                    'izq': (contexto(t, pr) or [('', 0)])[0][0]}
            if veredicto == 'repo':
                res['D1 equivocado'].append(fila)
            elif veredicto == 'd1':
                res['repo equivocado'].append(fila)
            else:
                res['sin decidir'].append(fila)
    for k, v in res.items():
        print(f'  {len(v):4}  {k}')
    (HERE / 'paridad_arbitrada.json').write_text(
        json.dumps(res, ensure_ascii=False, indent=1), encoding='utf-8')
    for k in ('D1 equivocado', 'repo equivocado', 'sin decidir'):
        if not res[k]:
            continue
        print(f'\n  {k}:')
        for x in res[k]:
            print(f"    {x['ref']:20} repo={x['repo'][:22]!r:26} D1={x['d1'][:22]!r}")
    return 0


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