"""Tests for core data models."""

from __future__ import annotations

from attestmcp.models import (
    AgentIdentity,
    AuditRecord,
    ChainVerification,
    IdentitySource,
    PolicyDecision,
    TrustLevel,
)


class TestAgentIdentity:
    """Identity model tests."""

    def test_anonymous_factory(self) -> None:
        identity = AgentIdentity.anonymous(session_id="sess-123")
        assert identity.source == IdentitySource.ANONYMOUS
        assert identity.trust_level == TrustLevel.ANONYMOUS
        assert identity.session_id == "sess-123"
        assert identity.user is None
        assert identity.verified is False

    def test_verified_identity(self) -> None:
        identity = AgentIdentity(
            source=IdentitySource.OAUTH_JWT,
            user="alice@example.com",
            agent_name="support-bot",
            org="acme-corp",
            role="read-only",
            verified=True,
            trust_level=TrustLevel.VERIFIED,
        )
        assert identity.verified is True
        assert identity.trust_level == TrustLevel.VERIFIED

    def test_serialization_roundtrip(self) -> None:
        identity = AgentIdentity(
            source=IdentitySource.OAUTH_JWT,
            user="test@test.com",
            verified=True,
            trust_level=TrustLevel.VERIFIED,
        )
        json_str = identity.model_dump_json()
        restored = AgentIdentity.model_validate_json(json_str)
        assert restored.user == identity.user
        assert restored.source == identity.source


class TestAuditRecord:
    """Audit record model tests."""

    def test_creates_with_defaults(self) -> None:
        record = AuditRecord(
            agent_identity=AgentIdentity.anonymous(),
            method="tools/call",
            params_hash="abc123",
        )
        assert record.record_id is not None
        assert record.timestamp is not None
        assert record.policy_decision == PolicyDecision.ALLOW
        assert record.chain_hash == ""
        assert record.duration_ms == 0

    def test_record_id_is_unique(self) -> None:
        r1 = AuditRecord(
            agent_identity=AgentIdentity.anonymous(),
            method="tools/call",
            params_hash="a",
        )
        r2 = AuditRecord(
            agent_identity=AgentIdentity.anonymous(),
            method="tools/call",
            params_hash="b",
        )
        assert r1.record_id != r2.record_id

    def test_serialization_roundtrip(self) -> None:
        record = AuditRecord(
            agent_identity=AgentIdentity(
                source=IdentitySource.OAUTH_JWT,
                user="test@test.com",
                verified=True,
                trust_level=TrustLevel.VERIFIED,
            ),
            method="tools/call",
            tool_name="store_memory",
            params_hash="abc",
            policy_decision=PolicyDecision.ALLOW,
            result_hash="def",
            duration_ms=12,
        )
        json_str = record.model_dump_json()
        restored = AuditRecord.model_validate_json(json_str)
        assert restored.record_id == record.record_id
        assert restored.agent_identity.user == "test@test.com"
        assert restored.tool_name == "store_memory"


class TestChainVerification:
    """Chain verification result model tests."""

    def test_empty_verification(self) -> None:
        v = ChainVerification.empty()
        assert v.valid is True
        assert v.records_checked == 0

    def test_failed_verification(self) -> None:
        v = ChainVerification(
            valid=False,
            records_checked=5,
            break_at_record_id="record-3",
            expected_hash="aaa",
            actual_hash="bbb",
        )
        assert v.valid is False
        assert v.break_at_record_id == "record-3"
