"""BTCQ SignatureHashMldsa — ported from btcqd interpreter.cpp."""
import struct
from electrum.btcq_crypto import sha3_256

SIGHASH_ALL = 1
SIGHASH_NONE = 2
SIGHASH_SINGLE = 3


def signature_hash_mldsa(version, inputs, outputs, script_code,
                          amount, n_in, hash_type, lock_time):
    """Compute BTCQ sighash matching btcqd's SignatureHashMldsa.

    inputs: list of {prevout_hash: bytes(32), prevout_n: int, sequence: int}
    outputs: list of {value: int, scriptPubKey: bytes}
    """
    s = bytearray()
    s += struct.pack('<i', version)
    for inp in inputs:
        s += inp['prevout_hash']
        s += struct.pack('<I', inp['prevout_n'])
        s += struct.pack('<I', inp['sequence'])
    s += _compact_size(len(script_code))
    s += script_code
    s += struct.pack('<q', amount)
    base_type = hash_type & 0x1f
    if base_type == SIGHASH_NONE:
        pass
    elif base_type == SIGHASH_SINGLE:
        if n_in < len(outputs):
            out = outputs[n_in]
            s += struct.pack('<q', out['value'])
            s += _compact_size(len(out['scriptPubKey']))
            s += out['scriptPubKey']
    else:
        for out in outputs:
            s += struct.pack('<q', out['value'])
            s += _compact_size(len(out['scriptPubKey']))
            s += out['scriptPubKey']
    s += struct.pack('<I', lock_time)
    s += struct.pack('<i', hash_type)
    return sha3_256(bytes(s))


def _compact_size(n):
    if n < 0xfd:
        return struct.pack('<B', n)
    elif n <= 0xffff:
        return b'\xfd' + struct.pack('<H', n)
    elif n <= 0xffffffff:
        return b'\xfe' + struct.pack('<I', n)
    else:
        return b'\xff' + struct.pack('<Q', n)
