from __future__ import annotations

import json

import pytest

from contract_attestation._verify import canonical_serialize, decrypt_findings, verify_response_hash


@pytest.mark.parametrize(
    "payload",
    [
        {"b": 2, "a": 1},
        {"z": {"b": 2, "a": 1}, "a": [3, 2, 1]},
    ],
)
def test_canonical_serialize_is_deterministic(payload: dict) -> None:
    first = canonical_serialize(payload)
    second = canonical_serialize(payload)

    assert first == second


def test_verify_response_hash_matches_keccak() -> None:
    web3 = pytest.importorskip("web3")

    payload = {
        "version": 2,
        "public": {"score": 99},
        "encrypted": {"ciphertext": "abcd"},
    }
    on_chain_hash = web3.Web3.keccak(canonical_serialize(payload)).hex()

    assert verify_response_hash(payload, on_chain_hash)
    assert not verify_response_hash(payload, "0x" + ("00" * 32))


def test_decrypt_findings_roundtrip() -> None:
    ecies = pytest.importorskip("ecies")
    coincurve = pytest.importorskip("coincurve")

    private_key = coincurve.PrivateKey()
    private_hex = private_key.to_hex()
    public_hex = private_key.public_key.format(compressed=False).hex()

    sensitive = {
        "findings": [{"severity": "high", "category": "reentrancy"}],
        "recommendations": ["Use checks-effects-interactions"],
    }
    ciphertext = ecies.encrypt(public_hex, json.dumps(sensitive).encode()).hex()

    decrypted = decrypt_findings({"encrypted": {"ciphertext": ciphertext}}, private_hex)

    assert decrypted == sensitive
