from __future__ import annotations

from oasyce.services.runtime_identity import (
    build_runtime_identity,
    normalize_runtime_actor,
    resolve_runtime_actor_trace,
    resolve_runtime_identity,
)


def test_build_runtime_identity_uses_account_status_and_session_metadata():
    payload = build_runtime_identity(
        account_status={
            "principal": {
                "id": "principal-1",
                "carrier_type": "owner_account",
                "carrier_id": "oasyce1acct",
                "delegate_type": "trusted_device",
                "delegate_id": "device-1",
                "bridge_model": True,
            },
            "account_address": "oasyce1acct",
            "account_mode": "attached_signing",
            "account_origin": "joined_existing",
            "device_id": "device-1",
            "device_authorization_status": "active",
            "can_sign": True,
        },
        default_agent_id="autonomy.operator",
        session_id="session-123",
        source="autonomy.status",
    )

    assert payload["principal"]["id"] == "principal-1"
    assert payload["account"] == {
        "id": "oasyce1acct",
        "type": "owner_account",
        "mode": "attached_signing",
        "origin": "joined_existing",
    }
    assert payload["delegate"] == {
        "id": "device-1",
        "type": "trusted_device",
        "authorization_status": "active",
        "can_sign": True,
    }
    assert payload["session"] == {
        "id": "session-123",
        "agent_id": "autonomy.operator",
        "source": "autonomy.status",
    }


def test_resolve_runtime_identity_degrades_cleanly_when_status_reader_fails():
    payload = resolve_runtime_identity(
        status_reader=lambda: (_ for _ in ()).throw(RuntimeError("boom")),
        default_agent_id="autonomy.operator",
        session_id="session-456",
        source="autonomy.status",
    )

    assert payload["principal"]["carrier_type"] == "owner_account"
    assert payload["principal"]["delegate_type"] == "trusted_device"
    assert payload["account"]["id"] == ""
    assert payload["delegate"]["id"] == ""
    assert payload["session"] == {
        "id": "session-456",
        "agent_id": "autonomy.operator",
        "source": "autonomy.status",
    }


def test_resolve_runtime_actor_trace_includes_nested_and_legacy_fields():
    payload = resolve_runtime_actor_trace(
        status_reader=lambda: {
            "principal": {
                "id": "principal-1",
                "carrier_type": "owner_account",
                "carrier_id": "oasyce1acct",
                "delegate_type": "trusted_device",
                "delegate_id": "device-1",
                "bridge_model": True,
            },
            "account_address": "oasyce1acct",
            "device_id": "device-1",
        },
        default_agent_id="autonomy.operator",
        session_id="session-789",
        source="scheduler.run",
    )

    assert payload["principal"]["id"] == "principal-1"
    assert payload["account"]["id"] == "oasyce1acct"
    assert payload["delegate"]["id"] == "device-1"
    assert payload["session"]["agent_id"] == "autonomy.operator"
    assert payload["owner_account"] == "oasyce1acct"
    assert payload["device_id"] == "device-1"
    assert payload["agent_id"] == "autonomy.operator"
    assert payload["session_id"] == "session-789"


def test_normalize_runtime_actor_upgrades_legacy_flat_actor():
    payload = normalize_runtime_actor(
        {
            "owner_account": "oasyce1acct",
            "device_id": "device-1",
            "agent_id": "autonomy.scheduler",
            "session_id": "session-1",
            "source": "scheduler.run",
        }
    )

    assert payload is not None
    assert payload["principal"]["id"] == "oasyce1acct"
    assert payload["account"]["id"] == "oasyce1acct"
    assert payload["delegate"]["id"] == "device-1"
    assert payload["session"]["agent_id"] == "autonomy.scheduler"
