#!/usr/bin/env python3
"""harkaq-add-deps — añade deps de build a una receta, sin romperla. (Cosecha desatendida.)

    harkaq-add-deps.py recipes/zlib.toml make binutils

Idempotente: si la dep ya está, no toca nada y sale 1 (nada que commitear).

Corre DESATENDIDO y de noche, editando ficheros que son la fuente de verdad del catálogo. Por eso
la regla es: **ante la duda, no tocar**. Un fichero mal editado a las 3am no da un error, da una
receta corrupta que nadie mira hasta el lunes. Cada caso que no se entiende sale sin cambios y con
motivo, que es la misma disciplina de `SinEvidencia`: no afirmar lo que no se sabe.
"""
import re
import sys


def anadir(path, nuevas):
    with open(path) as f:
        s = f.read()
    orig = s

    m = re.search(r'^\[deps\]\s*$(.*?)(?=^\[|\Z)', s, re.M | re.S)
    if m:
        bloque = m.group(1)
        mb = re.search(r'^(\s*build\s*=\s*)\[([^\]]*)\]', bloque, re.M)
        if mb:
            ya = re.findall(r'"([^"]+)"', mb.group(2))
            falta = [d for d in nuevas if d not in ya]
            if not falta:
                return False, "ya estaban declaradas"
            lista = ya + falta
            nuevo = mb.group(1) + "[" + ", ".join(f'"{d}"' for d in lista) + "]"
            s = s[:m.start(1)] + bloque[:mb.start()] + nuevo + bloque[mb.end():] + s[m.end(1):]
        else:
            # Hay [deps] pero sin `build = [...]` (p.ej. sólo `runtime`). Insertar la línea.
            linea = "build = [" + ", ".join(f'"{d}"' for d in nuevas) + "]\n"
            s = s[:m.start(1)] + "\n" + linea + bloque.lstrip("\n") + s[m.end(1):]
    else:
        # Sin [deps]: se añade al final. `[build.phases]` suele ser la última sección y sus strings
        # multilínea (''' … ''') se comerían un bloque puesto después ⇒ va ANTES de la primera
        # sección [build...] si existe, y si no, al final.
        bloque = "\n[deps]\nbuild = [" + ", ".join(f'"{d}"' for d in nuevas) + "]\n"
        mfase = re.search(r'^\[build\.phases\]', s, re.M)
        if mfase:
            s = s[:mfase.start()] + bloque.lstrip("\n") + "\n" + s[mfase.start():]
        else:
            s = s.rstrip("\n") + "\n" + bloque

    if s == orig:
        return False, "sin cambios"

    # Guarda: sólo escribir si el TOML sigue pareciendo un TOML y no perdimos nada. Un parser de
    # verdad sería mejor, pero tomllib no ESCRIBE y re-emitir con un writer reordenaría el fichero
    # entero (y con él, comentarios que valen oro en este repo).
    try:
        import tomllib
        tomllib.loads(s)
    except Exception as e:
        return False, f"el resultado no parsea como TOML ({e}) — NO se toca"
    if len(s) < len(orig):
        return False, "el resultado es más corto que el original — NO se toca"

    with open(path, "w") as f:
        f.write(s)
    return True, "ok"


def main():
    if len(sys.argv) < 3:
        print(__doc__.split("\n")[2].strip(), file=sys.stderr)
        return 2
    path, nuevas = sys.argv[1], sys.argv[2:]
    ok, motivo = anadir(path, nuevas)
    if not ok:
        print(f"   ·· {path}: {motivo}", file=sys.stderr)
    return 0 if ok else 1


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