from __future__ import annotations

from src.services.mcp_audit_context import (
    MAX_MCP_AUDIT_SESSION_ID_LENGTH,
    build_mcp_audit_context,
    normalize_mcp_audit_session_id,
    with_mcp_audit_context,
)


def test_build_mcp_audit_context_keeps_non_empty_fields() -> None:
    context = build_mcp_audit_context(
        session_id="incident:INC-1:pre_decision",
        incident_id="INC-1",
        flywheel_node="sense",
        agent_role="pre_decision_investigator",
        operator_user_id=None,
    )

    assert context == {
        "gateway_path": "legacy_registry_provider",
        "session_id": "incident:INC-1:pre_decision",
        "incident_id": "INC-1",
        "flywheel_node": "sense",
        "agent_role": "pre_decision_investigator",
    }


def test_normalize_mcp_audit_session_id_compacts_known_long_patterns() -> None:
    values = [
        (
            "incident:INC-20260505-E8033A:pre_decision",
            "inc:INC-20260505-E8033A:pre",
        ),
        (
            "incident:INC-20260505-E8033A:post_execution",
            "inc:INC-20260505-E8033A:post",
        ),
        (
            "callback:INC-20260505-E8033A:check_process",
            "cb:INC-20260505-E8033A",
        ),
        (
            "approval:123e4567-e89b-12d3-a456-426614174000",
            "apr:123e4567",
        ),
    ]

    for raw, expected_prefix in values:
        normalized = normalize_mcp_audit_session_id(raw)
        assert normalized is not None
        assert len(normalized) <= MAX_MCP_AUDIT_SESSION_ID_LENGTH
        assert normalized.startswith(expected_prefix)


def test_with_mcp_audit_context_merges_existing_context_without_mutating_source() -> None:
    params = {
        "namespace": "awoooi-prod",
        "_mcp_audit": {"trace_id": "trace-1", "flywheel_node": "old"},
    }

    audited = with_mcp_audit_context(
        params,
        incident_id="INC-2",
        flywheel_node="verify",
        agent_role="post_execution_verifier",
    )

    assert params["_mcp_audit"]["flywheel_node"] == "old"
    assert audited is not params
    assert audited["_mcp_audit"]["trace_id"] == "trace-1"
    assert audited["_mcp_audit"]["incident_id"] == "INC-2"
    assert audited["_mcp_audit"]["flywheel_node"] == "verify"
    assert audited["_mcp_audit"]["agent_role"] == "post_execution_verifier"
