import json

from mcard.model.pcard import PCard
from mcard.model.vcard import (
    Capability,
    CapabilityScope,
    VCard,
    create_vcard,
    get_pcard_refs,
    get_subject_did,
    is_vcard,
)

# =============================================================================
# PCard UPTV (Triad) Tests
# =============================================================================


def test_pcard_triad_accessors():
    """Test standard UPTV (Abstract, Concrete, Balanced) accessors."""
    clm_yaml = """
    abstract:
      thesis: "Specification"
    concrete:
      antithesis: "Implementation"
    balanced:
      synthesis: "Evidence"
    """
    pcard = PCard(clm_yaml)

    assert pcard.abstract["thesis"] == "Specification"
    assert pcard.concrete["antithesis"] == "Implementation"
    assert pcard.balanced["synthesis"] == "Evidence"


def test_pcard_legacy_accessors():
    """Test legacy aliases work for backward compatibility."""
    clm_yaml = """
    abstract:
      thesis: "Specification"
    concrete:
      antithesis: "Implementation"
    balanced:
      synthesis: "Evidence"
    """
    pcard = PCard(clm_yaml)

    # Legacy aliases verify against standard keys
    assert pcard.abstract_spec["thesis"] == "Specification"
    assert pcard.concrete_impl["antithesis"] == "Implementation"
    assert pcard.balanced_expectations["synthesis"] == "Evidence"


# =============================================================================
# VCard UPTV (Empty Schema) Tests
# =============================================================================


def test_vcard_creation_and_immutability_base():
    """Test VCard creation initializes immutable content correcty."""

    cap = Capability(
        capability_id="cap-1",
        actor_did="did:key:alice",
        scope=CapabilityScope.WRITE,
        resource_pattern=".*",
    )

    # Use Factory Function
    vcard = create_vcard(
        subject_did="did:key:bob", controller_pubkeys=["key1"], capabilities=[cap]
    )

    # Verify MCard content structure (Empty Schema)
    assert is_vcard(vcard)
    content = json.loads(vcard.get_content(as_text=True))
    assert content["vcard"]["identity"]["subject_did"] == "did:key:bob"
    assert content["vcard"]["gatekeeper"]["capabilities"][0]["id"] == "cap-1"

    # Verify Object View match
    assert vcard.subject_did == "did:key:bob"
    assert get_subject_did(vcard) == "did:key:bob"
    assert len(vcard.capabilities) == 1
    assert vcard.capabilities[0].capability_id == "cap-1"


def test_vcard_functional_helpers():
    """Test functional helpers (is_vcard, get_pcard_refs)."""

    content = {
        "vcard": {
            "type": "authentication-authorization",
            "identity": {"subject_did": "did:test:helper"},
            "verification": {"pcard_refs": [{"hash": "hash_1"}]},
        }
    }

    vcard = VCard(json.dumps(content), content_only=True)

    assert is_vcard(vcard)
    assert get_subject_did(vcard) == "did:test:helper"
    refs = get_pcard_refs(vcard)
    assert "hash_1" in refs


def test_vcard_mutable_runtime_state():
    """Test that VCard object allows runtime capability addition (Gateway Pattern)."""

    vcard = VCard(subject_did="did:key:server", controller_pubkeys=[])

    # Initial state
    assert len(vcard.capabilities) == 0

    # Add capability at runtime
    cap = Capability(
        capability_id="temp-1",
        actor_did="did:key:client",
        scope=CapabilityScope.READ,
        resource_pattern=".*",
    )
    vcard.add_capability(cap)

    # State updated
    assert len(vcard.capabilities) == 1
    assert vcard.capabilities[0].capability_id == "temp-1"
