# -*- coding: utf-8 -*-
r"""Recalcula os MD5 do CheckFileListW.ten depois de mexer nos .lod do client.

    python tools/atualizar_checkfilelist.py             mostra o que mudou
    python tools/atualizar_checkfilelist.py --aplicar   regrava o .ten

O ficheiro e uma lista de 760 caminhos com o MD5 de cada um, cifrada com a mesma subtracao
encadeada do ServerList.ten, seed 0x3042. Formato: primeira linha com a contagem, depois
"<caminho>\t<md5>" por linha, com o caminho a comecar em / e relativo a raiz do client.

O comentario no fazer_patch_client.py diz que a lista so cobre EIDString/EIDMain: esta
errado, conferido em 01/09. Cobre itemAttr (8 linhas) e ItemEnchant (16, contando as
fleta*), que sao precisamente as tabelas que se mexem para o refino ir ate +18.
"""
import argparse
import hashlib
import os
import sys

RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(RAIZ, "tools", "debug"))
from ten_crypto import decrypt_ten, encrypt_ten                     # noqa: E402

CLIENT = r"C:\Games\Axion"
LISTA = os.path.join(CLIENT, "CheckFileListW.ten")
SEED = 0x3042


def main() -> int:
    ap = argparse.ArgumentParser(description="Recalcula os MD5 do CheckFileListW.ten.")
    ap.add_argument("--aplicar", action="store_true")
    args = ap.parse_args()

    txt = decrypt_ten(open(LISTA, "rb").read(), SEED)
    if isinstance(txt, bytes):
        txt = txt.decode("latin-1")
    linhas = txt.split("\n")

    saida, mudou, faltam = [], [], 0
    for i, linha in enumerate(linhas):
        if i == 0 or "\t" not in linha:
            saida.append(linha)
            continue
        caminho, md5 = linha.split("\t", 1)
        real = os.path.join(CLIENT, caminho.lstrip("/").replace("/", os.sep))
        if not os.path.exists(real):
            faltam += 1
            saida.append(linha)
            continue
        novo = hashlib.md5(open(real, "rb").read()).hexdigest()
        if novo != md5.strip():
            mudou.append((caminho, md5.strip(), novo))
        saida.append("%s\t%s" % (caminho, novo))

    print("%d linhas | %d ficheiros nao existem no disco" % (len(linhas), faltam))
    print("%d hashes desactualizados:" % len(mudou))
    for c, v, n in mudou:
        print("   %-58s %s -> %s" % (c, v[:8], n[:8]))

    if not args.aplicar:
        print("\nnada gravado. corra com --aplicar")
        return 0
    if not mudou:
        print("\nnada a fazer.")
        return 0

    open(LISTA, "wb").write(encrypt_ten("\n".join(saida).encode("latin-1"), SEED))
    conf = decrypt_ten(open(LISTA, "rb").read(), SEED)
    if isinstance(conf, bytes):
        conf = conf.decode("latin-1")
    erro = 0
    for linha in conf.split("\n"):
        if "\t" not in linha:
            continue
        caminho, md5 = linha.split("\t", 1)
        real = os.path.join(CLIENT, caminho.lstrip("/").replace("/", os.sep))
        if os.path.exists(real) and hashlib.md5(open(real, "rb").read()).hexdigest() != md5.strip():
            erro += 1
    print("\ngravado. releitura: %d hashes errados" % erro)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
