# -*- coding: utf-8 -*-
r"""Extrai que ITEM cada skill consome, do skillBase do client.

    python tools/extrair_skill_item.py             mostra
    python tools/extrair_skill_item.py --aplicar   grava Data/Skills/SkillItem.ini

O client mostra na dica da skill "Objeto utilizado : Bala magica (1)" e o servidor nao sabia
disso -- a skill lancava-se sem gastar municao. O jogador viu em 01/09: "usa a skill mais
nao consome".

ONDE ESTA. No skillBase.lod, 68 bytes depois do id da skill:

    @ +68  u32  item_id do que se consome
    @ +72  u32  sempre 2 nas linhas boas -- serve de assinatura
    @ +76  u32  quantidade   (1 no "Golpe de forca", que e o (1) da dica)

Achado procurando o VALOR: o id da Bala magica (69507) aparece 29 vezes no ficheiro, e em
todas a mesma distancia do id de uma skill que existe.

ATENCAO AO PASSO DA VARREDURA: os registos NAO estao alinhados a 4 bytes. Com passo 4
apanhavam-se 11 das 53 skills, e a 15002 -- justamente a que o jogador estava a usar --
ficava de fora.
"""
import argparse
import os
import struct
import sys

RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(RAIZ, "tools"))
sys.path.insert(0, os.path.join(RAIZ, "server"))
import lod_crypto as L                                              # noqa: E402
import data_files                                                   # noqa: E402

LOD = r"C:\Games\Axion\ResUnpak\Interface\IE_Lod\skillBase.lod_pt"
SAIDA = os.path.join(RAIZ, "server", "Data", "Skills", "SkillItem.ini")
DESLOC = 68
ASSINATURA = 2
FIM = chr(10)


def extrair():
    d = L.decrypt_lod_stream(open(LOD, "rb").read())
    itens = data_files.indice("Item", "item_id")
    nomes = {}
    for r in data_files.tabela("SkillLod"):
        nomes.setdefault(int(r["skill_id"]), r.get("nome"))
    achados = {}
    for off in range(8, len(d) - DESLOC - 12):
        sid = struct.unpack_from("<I", d, off)[0]
        if sid not in nomes or sid in achados:
            continue
        iid, assin, qtd = struct.unpack_from("<3I", d, off + DESLOC)
        if assin == ASSINATURA and iid in itens and 0 <= qtd <= 100:
            achados[sid] = (iid, qtd, nomes.get(sid), itens[iid].get("nome"))
    return achados


def main() -> int:
    ap = argparse.ArgumentParser(description="Item consumido por cada skill.")
    ap.add_argument("--aplicar", action="store_true")
    args = ap.parse_args()
    a = extrair()
    print("%d skills consomem item" % len(a))
    import collections
    c = collections.Counter(v[0] for v in a.values())
    for iid, n in c.most_common(6):
        print("   %-10d %-32s %d skills" % (iid, str(a[next(k for k in a if a[k][0] == iid)][3])[:32], n))
    if not args.aplicar:
        print("\nnada gravado. junte --aplicar")
        return 0
    linhas = ["; SkillItem -- que item cada skill consome ao ser lancada.",
              "; colunas: skill_id, item_id, quantidade",
              ";",
              "; Do skillBase.lod do client: item em +68, assinatura 2 em +72, quantidade em +76",
              "; relativos ao id da skill. Ver tools/extrair_skill_item.py.",
              ";"]
    for i, sid in enumerate(sorted(a)):
        iid, qtd, nsk, nit = a[sid]
        linhas += ["; %s -> %s" % (nsk, nit),
                   "[%d]" % i, "skill_id = %d" % sid,
                   "item_id = %d" % iid, "quantidade = %d" % qtd]
    open(SAIDA, "wb").write((FIM.join(linhas) + FIM).encode("utf-8"))
    print("\ngravado: %s (%d skills)" % (SAIDA, len(a)))
    t = data_files.tabela("SkillItem")
    print("releitura: %d linhas" % len(t))
    return 0


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