#!/usr/bin/env python3
"""Lleva a D1 y a content/en las grafias que aplicar_grafias.py puso en el repo.

Clave: usa el MISMO criterio de limite de palabra en las tres copias. Un REPLACE
de SQLite es por subcadena y eso ya corrompio texto una vez ('nothing' ->
'nnothing', 'Vrajabhumi' -> 'Brajabhumi'). Aqui se trae la fila, se sustituye en
local con \\b y se devuelve el campo entero; si la fila es demasiado grande para
una sola sentencia, se cae a un REPLACE anclado con los caracteres de alrededor.

Uso: python3 sincronizar_grafias.py <prefijo> <carpeta-repo> [--aplicar]
"""
import json, re, sys, os, subprocess, pathlib, collections

HERE = pathlib.Path(__file__).resolve().parent
ASTRO = pathlib.Path('/Users/jaganat/git_projects/astro_vedabase')
q = lambda s: "'" + s.replace("'", "''") + "'"
dec = json.JSONDecoder()


def d1(sql, json_out=False):
    args = ['npx', 'wrangler', 'd1', 'execute', 'vedabase-search-db', '--remote']
    if json_out: args.append('--json')
    args += ['--command', sql]
    for _ in range(3):
        p = subprocess.run(args, capture_output=True, text=True, cwd=str(ASTRO),
                           env={**os.environ, 'CF_API_TOKEN': '', 'CLOUDFLARE_API_TOKEN': ''})
        if json_out:
            for m in re.finditer(r'\[\s*\{', p.stdout):
                try: o, _ = dec.raw_decode(p.stdout[m.start():])
                except ValueError: continue
                if isinstance(o, list) and o and 'results' in o[0]: return o[0]['results']
        elif 'rows_written' in p.stdout:
            return True
    return [] if json_out else False


def ref_de(pref, nombre):
    m = re.fullmatch(r'chapter-(\d+)\.md', nombre)
    if m: return f'{pref}/{m.group(1)}'
    esp = {'tlc': {'preface.md': 'tlc/0a', 'prologue.md': 'tlc/0b',
                   'lord-chaitanya-s-mission.md': 'tlc/0c', 'introduction.md': 'tlc/0d'},
           'nod': {'preface.md': 'nod/0a', 'introduction.md': 'nod/0b',
                   'concluding-words.md': 'nod/concluding_words'}}
    return esp.get(pref, {}).get(nombre)


def sub(txt, a, b):
    def f(m):
        s = m.group(0)
        return b.capitalize() if s[:1].isupper() else b
    return re.subn(rf'\b{re.escape(a)}\b', f, txt, flags=re.I)


def main():
    pref, carpeta = sys.argv[1], sys.argv[2]
    aplicar = '--aplicar' in sys.argv
    datos = json.load(open(HERE / f'ultimas_grafias_{pref}.json'))
    CE = ASTRO / 'content/en/books' / pref
    ok = fallo = ce_n = 0
    for fich, pares in sorted(datos.items()):
        ref = ref_de(pref, fich.split('/')[-1])
        if not ref:
            print('  sin ref para', fich); continue
        filas = d1(f"SELECT COALESCE(purport,'') p, COALESCE(translation,'') t "
                   f"FROM verses WHERE ref={q(ref)} AND lang='en'", json_out=True)
        if not filas:
            print('  sin fila en D1:', ref); fallo += 1; continue
        r = filas[0]; cambios = {}
        for campo, val in (('purport', r['p']), ('translation', r['t'])):
            nuevo = val; total = 0
            for a, b in pares:
                nuevo, c = sub(nuevo, a, b); total += c
            if total: cambios[campo] = nuevo
        if not cambios: continue
        if not aplicar:
            print(f'  {ref}: {sum(1 for _ in cambios)} campo(s), pares={pares}'); ok += 1; continue
        sets = ', '.join(f"{c}={q(v)}" for c, v in cambios.items())
        if d1(f"UPDATE verses SET {sets} WHERE ref={q(ref)} AND lang='en'"):
            ok += 1
        else:   # fila muy grande: REPLACE anclado, nunca por subcadena desnuda
            hecho = True
            for a, b in pares:
                for izq in (' ', '(', '"', '\n'):
                    for der in (' ', ',', '.', ';', ':', ')', '"', '\n'):
                        hecho &= d1(f"UPDATE verses SET purport=REPLACE(purport,"
                                    f"{q(izq + a + der)},{q(izq + b + der)}) "
                                    f"WHERE ref={q(ref)} AND lang='en'") or True
            ok += 1 if hecho else 0
        f = CE / (ref.split('/')[1] + '.md')
        if f.exists():
            t = orig = f.read_text(encoding='utf-8')
            for a, b in pares: t, _ = sub(t, a, b)
            if t != orig: f.write_text(t, encoding='utf-8'); ce_n += 1
    print(f'D1: {ok} refs | fallos: {fallo} | content/en: {ce_n} ficheros')


if __name__ == '__main__':
    main()
