"""Tests for electrum.btcq_sighash — BTCQ SignatureHashMldsa."""
import importlib.util
import os
import sys

_ELECTRUM_DIR = os.path.join(os.path.dirname(__file__), '..', 'electrum')

def _load(name, filename):
    spec = importlib.util.spec_from_file_location(name, os.path.join(_ELECTRUM_DIR, filename))
    mod = importlib.util.module_from_spec(spec)
    sys.modules[name] = mod
    spec.loader.exec_module(mod)
    return mod

_load('electrum.btcq_crypto', 'btcq_crypto.py')
sighash_mod = _load('electrum.btcq_sighash', 'btcq_sighash.py')
signature_hash_mldsa = sighash_mod.signature_hash_mldsa
SIGHASH_ALL = sighash_mod.SIGHASH_ALL
SIGHASH_NONE = sighash_mod.SIGHASH_NONE
SIGHASH_SINGLE = sighash_mod.SIGHASH_SINGLE


def _sample_tx():
    return dict(
        version=2,
        inputs=[{
            'prevout_hash': bytes(range(32)),
            'prevout_n': 0,
            'sequence': 0xffffffff,
        }],
        outputs=[{
            'value': 50_0000_0000,
            'scriptPubKey': bytes([0x00, 0x14] + list(range(20))),
        }],
        script_code=bytes([0x00, 0x14] + list(range(20))),
        amount=100_0000_0000,
        n_in=0,
        lock_time=0,
    )


def test_sighash_deterministic():
    tx = _sample_tx()
    h1 = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                               tx['script_code'], tx['amount'], tx['n_in'],
                               SIGHASH_ALL, tx['lock_time'])
    h2 = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                               tx['script_code'], tx['amount'], tx['n_in'],
                               SIGHASH_ALL, tx['lock_time'])
    assert h1 == h2
    assert len(h1) == 32


def test_sighash_all_vs_none():
    tx = _sample_tx()
    h_all = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                  tx['script_code'], tx['amount'], tx['n_in'],
                                  SIGHASH_ALL, tx['lock_time'])
    h_none = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                   tx['script_code'], tx['amount'], tx['n_in'],
                                   SIGHASH_NONE, tx['lock_time'])
    assert h_all != h_none


def test_sighash_all_vs_single():
    tx = _sample_tx()
    h_all = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                  tx['script_code'], tx['amount'], tx['n_in'],
                                  SIGHASH_ALL, tx['lock_time'])
    h_single = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                     tx['script_code'], tx['amount'], tx['n_in'],
                                     SIGHASH_SINGLE, tx['lock_time'])
    assert h_all != h_single


def test_sighash_none_vs_single():
    tx = _sample_tx()
    h_none = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                   tx['script_code'], tx['amount'], tx['n_in'],
                                   SIGHASH_NONE, tx['lock_time'])
    h_single = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                                     tx['script_code'], tx['amount'], tx['n_in'],
                                     SIGHASH_SINGLE, tx['lock_time'])
    assert h_none != h_single


def test_sighash_different_amounts():
    tx = _sample_tx()
    h1 = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                               tx['script_code'], 100, tx['n_in'],
                               SIGHASH_ALL, tx['lock_time'])
    h2 = signature_hash_mldsa(tx['version'], tx['inputs'], tx['outputs'],
                               tx['script_code'], 200, tx['n_in'],
                               SIGHASH_ALL, tx['lock_time'])
    assert h1 != h2


if __name__ == "__main__":
    tests = [f for f in dir() if f.startswith('test_')]
    for t in sorted(tests):
        print(f"  {t} ... ", end="", flush=True)
        globals()[t]()
        print("OK")
    print(f"\nAll {len(tests)} btcq_sighash tests passed.")
