# -*- coding: utf-8 -*-
"""Confere se as referencias entre os arquivos de Data/ apontam pra algo que existe.

    python tools/validar_data.py

Isto e o que o banco dava de graca com chave estrangeira e o arquivo nao da. Sem esta
checagem, uma missao pode pedir um item que nao existe e o erro so aparece quando um
jogador aceita a missao, meses depois. Rodar depois de todo exportar_data.py.
"""
import os
import sys

sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "server"))
import data_files as D                                              # noqa: E402

# (arquivo, coluna) -> (arquivo alvo, coluna alvo, aceita_zero)
REFERENCIAS = [
    ("Quest",          "doador_npc",    "Npc",   "npc_id",    True),
    ("Quest",          "pre_requisito", "Quest", "quest_id",  True),
    ("QuestReward",    "quest_id",      "Quest", "quest_id",  False),
    ("QuestReward",    "item_id",       "Item",  "item_id",   False),
    ("ClassEvolution", "vem_de",        "Class", "classe_id", False),
    ("ClassEvolution", "requisito",     "Item",  "item_id",   True),
    ("ClassStartItem", "classe_id",     "Class", "classe_id", False),
    ("ClassStartItem", "item_id",       "Item",  "item_id",   False),
    ("ItemOption",     "item_id",       "Item",  "item_id",   False),
]

# O alvo da missao muda de tabela conforme o tipo, entao vai separado.
TIPO_ALVO = {1: ("Npc", "npc_id"), 3: ("Item", "item_id"), 8: ("Npc", "npc_id")}


def main() -> int:
    D.carregar()
    problemas = 0

    for arq, col, alvo_arq, alvo_col, aceita_zero in REFERENCIAS:
        linhas = D.tabela(arq)
        if not linhas:
            print("%-16s %-15s  arquivo vazio ou ausente" % (arq, col))
            continue
        if col not in linhas[0]:
            print("%-16s %-15s  COLUNA NAO EXISTE" % (arq, col))
            problemas += 1
            continue
        validos = set(D.indice(alvo_arq, alvo_col))
        soltos = set()
        for r in linhas:
            v = r.get(col)
            if v is None:
                continue
            if aceita_zero and v == 0:
                continue
            if v not in validos:
                soltos.add(v)
        marca = "ok" if not soltos else "%d valores sem destino" % len(soltos)
        print("%-16s %-15s -> %-6s %-11s %s" % (arq, col, alvo_arq, alvo_col, marca))
        if soltos:
            problemas += len(soltos)
            print("%38s exemplos: %s" % ("", sorted(soltos)[:6]))

    print()
    print("--- alvo da missao, por tipo ---")
    faltando = {}
    for r in D.tabela("Quest"):
        par = TIPO_ALVO.get(r.get("tipo"))
        if not par:
            continue
        if r.get("alvo") not in set(D.indice(par[0], par[1])):
            faltando.setdefault(r["tipo"], []).append((r["quest_id"], r["alvo"]))
    for tipo, lista in sorted(faltando.items()):
        print("   tipo %d: %d missoes com alvo inexistente, ex.: %s"
              % (tipo, len(lista), lista[:3]))
        problemas += len(lista)
    if not faltando:
        print("   ok -- todo alvo de missao existe na tabela do seu tipo")

    print()
    print("%d problema(s)" % problemas)
    return 1 if problemas else 0


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