"""Tests for the pluggable signer backends and the detached-envelope helpers.

Covers the KMSSigner production seam (including its refuse-to-fall-back-to-local
guarantee) and the backend-independent sign_payload/verify_payload roundtrip with
trusted-key pinning.
"""
import base64

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

from abom import sign
from abom.signer import (
    KMSSigner,
    LocalSigner,
    sign_payload,
    verify_payload,
)


def _raw_pub_b64(key: Ed25519PrivateKey) -> str:
    from cryptography.hazmat.primitives import serialization
    raw = key.public_key().public_bytes(
        serialization.Encoding.Raw, serialization.PublicFormat.Raw
    )
    return base64.b64encode(raw).decode()


# --------------------------------------------------------------------------
# LocalSigner + envelope roundtrip
# --------------------------------------------------------------------------
def test_local_signer_envelope_roundtrip(tmp_path):
    signer = LocalSigner(sign.load_or_create_key(tmp_path / "k.pem"))
    payload = b"tree-head-bytes"
    env = sign_payload(signer, payload)
    assert env["alg"] == "ed25519"
    assert env["backend"] == "local"
    assert verify_payload(payload, env) is True
    # tampered payload fails
    assert verify_payload(b"different", env) is False


def test_verify_payload_trusted_key_pinning(tmp_path):
    signer = LocalSigner(sign.load_or_create_key(tmp_path / "k.pem"))
    env = sign_payload(signer, b"x")
    kid = env["key_id"]
    assert verify_payload(b"x", env, trusted_key_ids={kid}) is True
    assert verify_payload(b"x", env, trusted_key_ids={"deadbeefdeadbeef"}) is False


def test_verify_payload_bad_envelope_returns_false():
    assert verify_payload(b"x", {"pub": "not-base64!!", "value": "z"}) is False
    assert verify_payload(b"x", {}) is False


# --------------------------------------------------------------------------
# KMSSigner — the production seam
# --------------------------------------------------------------------------
def test_kms_signer_uses_wired_callable(tmp_path):
    """A wired kms_sign callable produces a verifiable signature."""
    key = Ed25519PrivateKey.generate()
    pub_b64 = _raw_pub_b64(key)

    calls = []

    def kms_sign(key_ref, message):
        calls.append((key_ref, message))
        return key.sign(message)

    signer = KMSSigner("arn:aws:kms:...:key/abc", pub_b64, kms_sign=kms_sign)
    assert signer.backend == "kms"
    env = sign_payload(signer, b"payload")
    assert verify_payload(b"payload", env) is True
    assert calls and calls[0][0] == "arn:aws:kms:...:key/abc"


def test_kms_signer_refuses_to_fall_back_to_local():
    """Unwired, KMSSigner raises rather than silently signing with a local key —
    the security-critical guarantee."""
    key = Ed25519PrivateKey.generate()
    signer = KMSSigner("some-ref", _raw_pub_b64(key))  # no kms_sign wired
    with pytest.raises(NotImplementedError, match="Refusing to fall back"):
        signer.sign(b"x")


def test_kms_signer_validates_public_key():
    with pytest.raises(Exception):
        KMSSigner("ref", "not-a-valid-ed25519-key")


def test_kms_signer_key_id_matches_local_of_same_key():
    key = Ed25519PrivateKey.generate()
    pub_b64 = _raw_pub_b64(key)
    kms = KMSSigner("ref", pub_b64, kms_sign=lambda r, m: key.sign(m))
    local = LocalSigner(key)
    assert kms.key_id() == local.key_id()
