from __future__ import annotations

import pytest
from botindex_aar.sign import generate_key_pair, load_secret_key, sign_receipt
from botindex_aar.verify import verify_receipt
from botindex_aar.receipt import create_receipt
from botindex_aar.hash import hash_input, hash_output


def test_generate_key_pair() -> None:
    keys = generate_key_pair()
    assert len(bytes(keys.publicKey)) == 32
    assert len(keys.secretKey) == 64  # PyNaCl expanded secret key


def test_sign_and_verify_roundtrip() -> None:
    keys = generate_key_pair()
    receipt = create_receipt({
        "receiptId": "test-001",
        "timestamp": "2026-03-06T12:00:00.000Z",
        "agent": {"id": "agent:test", "name": "TestAgent", "version": "1.0.0"},
        "principal": {"id": "user:test", "type": "user"},
        "action": {"type": "test.action", "target": "unit-test", "method": "GET", "status": "success"},
        "scope": {"permissions": ["test.read"], "constraints": {}},
        "inputHash": hash_input({"query": "test"}),
        "outputHash": hash_output("test-result"),
        "cost": {"amount": "0.01", "currency": "USDC"},
        "signature": {"kid": "agent:test#key-1"},
        "metadata": {},
    })
    signed = sign_receipt(receipt, keys.secretKey)
    assert "sig" in signed["signature"]
    assert signed["signature"]["alg"] == "Ed25519"
    assert signed["signature"]["canonicalization"] == "JCS-SORTED-UTF8-NOWS"

    result = verify_receipt(signed, keys.publicKey)
    assert result.ok is True


def test_verify_fails_with_wrong_key() -> None:
    keys1 = generate_key_pair()
    keys2 = generate_key_pair()
    receipt = create_receipt({
        "receiptId": "test-002",
        "timestamp": "2026-03-06T12:00:00.000Z",
        "agent": {"id": "agent:test", "name": "TestAgent", "version": "1.0.0"},
        "principal": {"id": "user:test", "type": "user"},
        "action": {"type": "test.action", "target": "unit-test", "method": "GET", "status": "success"},
        "scope": {"permissions": ["test.read"], "constraints": {}},
        "inputHash": hash_input({"query": "test"}),
        "outputHash": hash_output("test-result"),
        "cost": {"amount": "0.01", "currency": "USDC"},
        "signature": {"kid": "agent:test#key-1"},
        "metadata": {},
    })
    signed = sign_receipt(receipt, keys1.secretKey)
    result = verify_receipt(signed, keys2.publicKey)
    assert result.ok is False


def test_verify_fails_with_tampered_receipt() -> None:
    keys = generate_key_pair()
    receipt = create_receipt({
        "receiptId": "test-003",
        "timestamp": "2026-03-06T12:00:00.000Z",
        "agent": {"id": "agent:test", "name": "TestAgent", "version": "1.0.0"},
        "principal": {"id": "user:test", "type": "user"},
        "action": {"type": "test.action", "target": "unit-test", "method": "GET", "status": "success"},
        "scope": {"permissions": ["test.read"], "constraints": {}},
        "inputHash": hash_input({"query": "test"}),
        "outputHash": hash_output("test-result"),
        "cost": {"amount": "0.01", "currency": "USDC"},
        "signature": {"kid": "agent:test#key-1"},
        "metadata": {},
    })
    signed = sign_receipt(receipt, keys.secretKey)
    # Tamper with the receipt
    signed["action"]["target"] = "tampered"
    result = verify_receipt(signed, keys.publicKey)
    assert result.ok is False


def test_load_secret_key_from_seed() -> None:
    seed = bytes(range(32))
    sk = load_secret_key(seed)
    assert sk is not None  # Expanded Ed25519 secret key
