"""Signs a Myntkaup API request with the `cryptography` package (Python 3.9+).

test/samples.test.ts checks it against packages/signing/test-vectors.json.
"""

import base64
import hashlib
import secrets
import time

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey


def sign_headers(key_id, private_key, method, path_and_query, body=b"", timestamp=None, nonce=None):
    """Returns the four MK-* headers. `body` must be the exact bytes you send."""
    if isinstance(body, str):
        body = body.encode("utf-8")
    seed = base64.urlsafe_b64decode(private_key.removeprefix("mk_sk_") + "=")
    key = Ed25519PrivateKey.from_private_bytes(seed)
    timestamp = str(timestamp if timestamp is not None else int(time.time() * 1000))
    nonce = nonce or secrets.token_hex(16)
    canonical = "\n".join(
        [
            "myntkaup-public-v1",
            key_id,
            timestamp,
            nonce,
            method.upper(),
            path_and_query,
            hashlib.sha256(body).hexdigest(),
        ]
    )
    signature = base64.b64encode(key.sign(canonical.encode("utf-8"))).decode("ascii")
    return {
        "MK-Key-Id": key_id,
        "MK-Timestamp": timestamp,
        "MK-Nonce": nonce,
        "MK-Signature": signature,
    }
