# -*- coding: utf-8 -*-
r"""Cadastra, confere ou remove a segunda senha (PIN) de uma conta.

    python tools/segunda_senha.py <conta>              diz se a conta tem PIN
    python tools/segunda_senha.py <conta> 123456       cadastra ou troca
    python tools/segunda_senha.py <conta> --apagar     remove
    python tools/segunda_senha.py <conta> --conferir 123456

PORQUE ISTO EXISTE, E NAO A JANELA DE CADASTRO DO JOGO. A janela 30037 ("Criar uma
segunda senha", com os dois campos) existe no script e a classe dela existe no binario,
mas ABRI-LA FECHA O JOGO: medido pelo log de eventos do Windows, excepcao 0xc0000005 no
deslocamento 0x00055603 -- `MOVZX EAX,byte [ECX+0x5e]` com ECX invalido.

A culpa nao e do patch. FUN_005a3234, que o OnOpen dela chama no fim, faz
    *(this + 0xbc) + 0xa1 = 1
    iVar = **(int **)(this + 0x140)
    (**(code **)(iVar + 0x48))(...)
sem testar nulo em lado nenhum, e os subctrl 35 e 36 da 30037 sao txtPasswd (GUI.ID
4053), tipo diferente dos txtTitle que a 30039 usa. O que preparava esses ponteiros
antes de a janela abrir foi arrancado do binario com o resto da funcionalidade.

Ate isso estar medido, o PIN cadastra-se aqui e o jogo so o confere -- que e a parte
que ja funciona ponta a ponta: a janela 30039 abre, aceita o PIN, e o servidor tranca
o 02 04 de quem nao conferiu.

O PIN tem de ter 6 digitos: e o que o client valida antes de enviar (FUN_005a4a8e
recusa com menos de 6 e mostra a cadeia 31988, "A senha deve ter 6 numeros").
"""
import os
import sys

RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(RAIZ, "server"))
import db                                                          # noqa: E402


def main() -> int:
    if len(sys.argv) < 2:
        print(__doc__)
        return 1
    conta = sys.argv[1]
    resto = sys.argv[2:]

    if not resto:
        tem = db.tem_segunda_senha(conta)
        print("conta '%s': %s" % (conta, "TEM segunda senha" if tem else "sem segunda senha"))
        return 0

    if resto[0] == "--apagar":
        ok = db.apagar_segunda_senha(conta)
        print("removida." if ok else "nao havia nada para remover (ou a conta nao existe).")
        return 0 if ok else 1

    if resto[0] == "--conferir":
        if len(resto) < 2:
            print("falta o PIN a conferir.")
            return 1
        ok = db.conferir_segunda_senha(conta, resto[1])
        print("CONFERE." if ok else "NAO CONFERE.")
        return 0 if ok else 1

    pin = resto[0]
    if not (pin.isdigit() and len(pin) == 6):
        print("o PIN tem de ser 6 digitos -- e o que o client valida antes de enviar.")
        return 1
    if not db.definir_segunda_senha(conta, pin):
        print("nao deu para cadastrar. A conta '%s' existe?" % conta)
        return 1
    print("cadastrada para '%s'." % conta)
    print("a partir de agora o servidor recusa o 02 04 dessa conta ate a janela")
    print("da segunda senha conferir o PIN.")
    return 0


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