"""
E2E Test: Core to AAA MCP Pipeline

Tests the complete constitutional pipeline from init_session through vault_seal.
Verifies:
1. init_session outputs DITEMPA, BUKAN DIBERI with 🔥 emoji
2. vault_seal outputs DITEMPA, BUKAN DIBERI with 💎🧠🔒 emoji
3. All constitutional floors are enforced
4. Session flows correctly through all stages

DITEMPA BUKAN DIBERI — Forged, Not Given
"""

import pytest
import asyncio
from typing import Dict, Any

# Skip tests if core modules unavailable
try:
    from aaa_mcp.protocol.tool_graph import WORKFLOW_SEQUENCES, validate_sequence
    from aaa_mcp.protocol.capabilities import TOOL_CAPABILITIES
    from aaa_mcp.protocol.response import (
        build_init_response,
        build_seal_response,
        build_verdict_response,
    )

    CORE_AVAILABLE = True
except ImportError:
    CORE_AVAILABLE = False


pytestmark = pytest.mark.skipif(not CORE_AVAILABLE, reason="Core modules not available")


class TestConstitutionalPipeline:
    """E2E tests for the 000-999 constitutional pipeline."""

    def test_init_session_has_motto_with_fire_emoji(self):
        """🔥 init_session must output DITEMPA, BUKAN DIBERI with fire emoji."""
        response = build_init_response(
            session_id="test-session-001", verdict="SEAL", mode="conscience"
        )

        # Check message contains motto with fire emoji
        assert "🔥" in response.message, "INIT gate must have 🔥 emoji"
        assert "DITEMPA" in response.message, "INIT gate must have DITEMPA"
        assert "BUKAN DIBERI" in response.message, "INIT gate must have BUKAN DIBERI"

        # Check data contains motto metadata
        assert response.data.get("motto") == "DITEMPA, BUKAN DIBERI"
        assert response.data.get("motto_english") == "Forged, Not Given"
        assert response.data.get("motto_emojis") == "🔥"
        assert response.data.get("bookend") == "INIT"

        print(f"✅ init_session: {response.message}")

    def test_vault_seal_has_motto_with_diamond_brain_lock(self):
        """💎🧠🔒 VAULT seal must output DITEMPA, BUKAN DIBERI with diamond/brain/lock emojis."""
        response = build_seal_response(
            session_id="test-session-001",
            seal_id="seal_abc123xyz",
            seal_hash="a1b2c3d4e5f6...",
            verdict="SEALED",
        )

        # Check message contains motto with diamond/brain/lock emojis
        assert "💎" in response.message, "VAULT seal must have 💎 emoji"
        assert "🧠" in response.message, "VAULT seal must have 🧠 emoji"
        assert "🔒" in response.message, "VAULT seal must have 🔒 emoji"
        assert "DITEMPA" in response.message, "VAULT seal must have DITEMPA"
        assert "BUKAN DIBERI" in response.message, "VAULT seal must have BUKAN DIBERI"

        # Check data contains motto metadata
        assert response.data.get("motto") == "DITEMPA, BUKAN DIBERI"
        assert response.data.get("motto_english") == "Forged, Not Given"
        assert "💎🧠🔒" in response.data.get(
            "motto_emojis", ""
        ), "VAULT seal must have 💎🧠🔒 emojis"
        assert response.data.get("bookend") == "SEAL"

        print(f"✅ VAULT seal: {response.message}")

    def test_emojis_are_different_for_init_vs_seal(self):
        """INIT and SEAL must have contrasting emojis."""
        init_response = build_init_response(session_id="test-session-001", verdict="SEAL")
        seal_response = build_seal_response(
            session_id="test-session-001",
            seal_id="seal_abc123",
            seal_hash="hash...",
            verdict="SEALED",
        )

        init_emojis = init_response.data.get("motto_emojis", "")
        seal_emojis = seal_response.data.get("motto_emojis", "")

        # Emojis must be different
        assert init_emojis != seal_emojis, "INIT and SEAL must have different emojis"

        # INIT should have fire
        assert "🔥" in init_emojis, "INIT must have fire emoji"

        # SEAL should have diamond/brain/lock
        assert (
            "💎" in seal_emojis or "🧠" in seal_emojis or "🔒" in seal_emojis
        ), "SEAL must have diamond/brain/lock emojis"

        print(f"✅ INIT emojis: {init_emojis}")
        print(f"✅ SEAL emojis: {seal_emojis}")

    def test_workflow_sequences_are_valid(self):
        """All workflow sequences must pass constitutional validation."""
        workflows = WORKFLOW_SEQUENCES

        for name, sequence in workflows.items():
            is_valid, msg = validate_sequence(sequence)
            assert is_valid, f"Workflow '{name}' invalid: {msg}"
            print(f"✅ Workflow '{name}' valid: {' -> '.join(sequence)}")

    def test_all_tools_have_capability_descriptions(self):
        """Every tool in graph must have capability description."""
        from aaa_mcp.protocol.tool_graph import TOOL_GRAPH

        for tool_name in TOOL_GRAPH.keys():
            assert (
                tool_name in TOOL_CAPABILITIES
            ), f"Tool '{tool_name}' missing capability description"

            cap = TOOL_CAPABILITIES[tool_name]
            assert cap.floors_enforced is not None, f"Tool '{tool_name}' missing floors_enforced"
            assert cap.when_to_use, f"Tool '{tool_name}' missing when_to_use guidance"

            print(f"✅ Tool '{tool_name}' has full capability description")

    def test_apex_verdict_path_has_unified_entrypoint(self):
        """trinity_forge must remain available as unified entrypoint for apex path."""
        from aaa_mcp.protocol.tool_graph import TOOL_GRAPH

        assert "trinity_forge" in TOOL_GRAPH, "trinity_forge must exist in tool graph"

        node = TOOL_GRAPH["trinity_forge"]
        assert node.must_call_first, "trinity_forge must be callable first"
        assert node.terminal, "trinity_forge must be terminal (complete pipeline)"

        # Check it's in quick_decision workflow
        assert (
            "trinity_forge" in WORKFLOW_SEQUENCES["quick_decision"]
        ), "trinity_forge must be in quick_decision workflow"

        print("✅ trinity_forge is valid unified entrypoint")

    def test_schema_versions_are_current(self):
        """Tool/resource schema versions should match current deployment date."""
        from aaa_mcp.core.motto_schema import get_mottos_resource

        init_response = build_init_response(session_id="test-session-001", verdict="SEAL")
        debug_payload = init_response.to_dict(debug=True)

        assert debug_payload["_schema"]["schema_version"] == "2026.02.22-AUTHORITY"
        assert debug_payload["_schema"]["policy_version"] == "2026.02.22-FORGE"

        mottos = get_mottos_resource()
        assert mottos["text"]["schema_version"] == "2026.02.22-CORE"


class TestAuthenticationRelaxed:
    """Tests that authentication is relaxed for pilot phase."""

    def test_auth_token_is_optional(self):
        """auth_token parameter must be optional for all tools."""
        from aaa_mcp.protocol.schemas import TOOL_INPUT_SCHEMAS

        # Check trinity_forge schema
        forge_schema = TOOL_INPUT_SCHEMAS.get("trinity_forge", {})
        props = forge_schema.get("properties", {})

        if "auth_token" in props:
            # auth_token exists but should not be in required
            assert "auth_token" not in forge_schema.get(
                "required", []
            ), "auth_token must be optional (not required)"
            # And should accept null
            auth_type = props["auth_token"].get("type", [])
            assert "null" in auth_type or "string" in str(
                auth_type
            ), "auth_token must accept null for pilot phase"

        print("✅ auth_token is optional for pilot phase")

    def test_init_session_no_strict_auth(self):
        """init_session should not require strict authentication."""
        try:
            from aaa_mcp.core.constitutional_decorator import _build_pre_context
        except ImportError:
            pytest.skip(
                "_build_pre_context is private/optional; auth optionality is covered by schema test"
            )

        ctx = _build_pre_context("test query", {"session_id": "test-123"})

        # Should have auto-authentication for MCP tools
        assert ctx.get("role") == "AGENT", "MCP tools auto-authenticate as AGENT"
        assert (
            ctx.get("authority_token") == "arifos_mcp"
        ), "MCP tools should use arifos_mcp authority token"

        print("✅ Authentication relaxed for pilot: auto-authenticated as AGENT")


class TestEndToEndFlow:
    """Full E2E flow tests."""

    @pytest.mark.anyio
    async def test_full_pipeline_flow(self):
        """Test complete 000-999 pipeline execution."""
        # This verifies sequence semantics via graph naming mapped to canonical tool names.
        sequence = WORKFLOW_SEQUENCES["full_analysis"]

        canonical_alias = {
            "init_gate": "init_session",
            "agi_sense": "agi_cognition",
            "agi_think": "agi_cognition",
            "agi_reason": "agi_cognition",
            "asi_empathize": "asi_empathy",
            "asi_align": "asi_empathy",
            "apex_verdict": "apex_verdict",
            "vault_seal": "vault_seal",
            "reality_search": "search",
        }
        canonical_sequence = [canonical_alias.get(stage, stage) for stage in sequence]

        assert canonical_sequence[0] == "init_session"
        assert "agi_cognition" in canonical_sequence
        assert "asi_empathy" in canonical_sequence
        assert canonical_sequence[-2] == "apex_verdict"
        assert canonical_sequence[-1] == "vault_seal"

        print(f"✅ Full pipeline sequence verified (canonical): {' -> '.join(canonical_sequence)}")

    def test_bookend_mottos_match(self):
        """INIT and SEAL bookends must share DITEMPA motto."""
        init = build_init_response("test", "SEAL")
        seal = build_seal_response("test", "seal-123", "hash...", "SEALED")

        # Both must have same motto
        assert init.data["motto"] == seal.data["motto"] == "DITEMPA, BUKAN DIBERI"

        # But different bookend markers
        assert init.data["bookend"] == "INIT"
        assert seal.data["bookend"] == "SEAL"

        # And different emojis (fire vs diamond/brain/lock)
        assert init.data["motto_emojis"] == "🔥"
        assert "💎" in seal.data["motto_emojis"]
        assert "🧠" in seal.data["motto_emojis"]

        print("✅ Bookend design verified: DITEMPA at both gates with contrasting emojis")


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
