#!/usr/bin/env python3
"""
Test suite for Constitutional Codex MCP integration
Tests all constitutional tools and trinity coordination
"""

import asyncio
import pytest
import json
from typing import Dict, List, Any
from unittest.mock import Mock, patch, AsyncMock

# arifOS components
from arifos_core.mcp.codex_client import ConstitutionalCodexClient, ConstitutionalCodexResponse
from arifos_core.mcp.tools.codex_skills import CodexConstitutionalSkills, CodeVerdict
from arifos_core.trinity.coordinator import TrinityCoordinator, TrinityResult, CodexTrinitySynthesis
from arifos_core.system.apex_prime import Verdict


class TestConstitutionalCodexClient:
    """Test Constitutional Codex Client"""
    
    @pytest.fixture
    async def codex_client(self):
        """Create test Codex client"""
        client = ConstitutionalCodexClient(
            api_key="test_api_key",
            user_id="test_user"
        )
        return client
    
    @pytest.mark.asyncio
    async def test_constitutional_request_processing(self, codex_client):
        """Test constitutional request processing"""
        
        query = "Analyze this code for security vulnerabilities"
        intent = "code_analysis"
        
        result = await codex_client.process_constitutional_request(
            query=query,
            intent=intent
        )
        
        assert isinstance(result, ConstitutionalCodexResponse)
        assert result.verdict in [Verdict.SEAL, Verdict.PARTIAL, Verdict.VOID, Verdict.SABAR]
        assert result.session_id is not None
        assert result.execution_time_ms > 0
    
    @pytest.mark.asyncio
    async def test_intent_validation(self, codex_client):
        """Test F1 Amanah intent validation"""
        
        # Valid intent
        valid_result = await codex_client.process_constitutional_request(
            query="Generate code for user authentication",
            intent="code_generation"
        )
        
        assert valid_result.verdict != Verdict.VOID or "F1 Amanah" not in valid_result.reason
        
        # Invalid intent
        invalid_result = await codex_client.process_constitutional_request(
            query="Generate code",
            intent="x"  # Too short
        )
        
        assert invalid_result.verdict == Verdict.VOID or len(invalid_result.reason) > 0
    
    @pytest.mark.asyncio
    async def test_f4_clarity_enforcement(self, codex_client):
        """Test F4 Clarity constitutional floor enforcement"""
        
        # High entropy query (should trigger SABAR)
        high_entropy_query = "a" * 1000 + " eval() " + "b" * 1000
        
        result = await codex_client.process_constitutional_request(
            query=high_entropy_query,
            intent="test"
        )
        
        # Should either be SABAR or have constitutional processing
        assert result.verdict in [Verdict.SABAR, Verdict.VOID, Verdict.SEAL, Verdict.PARTIAL]
    
    @pytest.mark.asyncio
    async def test_session_management(self, codex_client):
        """Test constitutional session management"""
        
        # Create session
        session_id = "test_session_1"
        result1 = await codex_client.process_constitutional_request(
            query="First query",
            session_id=session_id
        )
        
        assert result1.session_id == session_id
        
        # Continue session
        result2 = await codex_client.process_constitutional_request(
            query="Second query",
            session_id=session_id
        )
        
        assert result2.session_id == session_id
        
        # Check session history was maintained
        session = codex_client.session_manager.get_session(session_id)
        assert session is not None
        assert len(session["conversation_history"]) >= 2
    
    @pytest.mark.asyncio
    async def test_tool_selection(self, codex_client):
        """Test constitutional tool selection"""
        
        # Code analysis query
        code_query = "Analyze this code: def test(): pass"
        tool_selection = codex_client._select_constitutional_tools(code_query, "code_analysis", {})
        
        assert "codex_code_analysis" in tool_selection["tools"]
        
        # General query
        general_query = "What is constitutional governance?"
        tool_selection = codex_client._select_constitutional_tools(general_query, "general", {})
        
        assert "arifos_live" in tool_selection["tools"]
    
    @pytest.mark.asyncio
    async def test_cryptographic_sealing(self, codex_client):
        """Test cryptographic sealing for valid operations"""
        
        result = await codex_client.process_constitutional_request(
            query="Generate a simple function",
            intent="code_generation"
        )
        
        if result.verdict in [Verdict.SEAL, Verdict.PARTIAL]:
            assert result.seal is not None
            assert result.seal.startswith("CODEX_SEAL:")
    
    def test_system_status(self, codex_client):
        """Test system status reporting"""
        
        status = codex_client.get_system_status()
        
        assert "openai_available" in status
        assert "mock_mode" in status
        assert "session_count" in status
        assert "tool_count" in status
        assert status["constitutional_compliance"] is True


class TestCodexConstitutionalSkills:
    """Test Codex Constitutional Skills"""
    
    @pytest.fixture
    def codex_skills(self):
        """Create test Codex skills"""
        return CodexConstitutionalSkills(user_id="test_user")
    
    @pytest.mark.asyncio
    async def test_code_analysis(self, codex_skills):
        """Test constitutional code analysis"""
        
        test_code = '''
def process_user_data(user_input):
    """Process user data with basic validation"""
    if len(user_input) > 0:
        processed = user_input.strip().lower()
        return processed
    return None
'''
        
        result = await codex_skills.analyze_code(
            code=test_code,
            analysis_type="security",
            user_id="test_user"
        )
        
        assert result["verdict"] in [CodeVerdict.CODE_SEAL.value, CodeVerdict.CODE_PARTIAL.value, 
                                     CodeVerdict.CODE_VOID.value, CodeVerdict.CODE_SABAR.value]
        assert "security_score" in result
        assert "constitutional_compliance" in result
        assert "agi_insights" in result
        assert len(result["agi_insights"]) > 0
    
    @pytest.mark.asyncio
    async def test_code_generation(self, codex_skills):
        """Test constitutional code generation"""
        
        requirements = "Create a function to validate email addresses"
        constraints = ["Must be secure", "Must handle edge cases", "Must be readable"]
        
        result = await codex_skills.generate_code(
            requirements=requirements,
            constraints=constraints,
            user_id="test_user",
            language="python",
            complexity_level="moderate"
        )
        
        assert result["verdict"] in [CodeVerdict.CODE_SEAL.value, CodeVerdict.CODE_PARTIAL.value,
                                     CodeVerdict.CODE_VOID.value, CodeVerdict.CODE_SABAR.value]
        assert "generated_code" in result
        assert len(result["generated_code"]) > 0
        assert "complexity_score" in result
        assert "clarity_score" in result
        assert "trinity_validation" in result
    
    @pytest.mark.asyncio
    async def test_f6_clarity_enforcement(self, codex_skills):
        """Test F6 Clarity enforcement in code"""
        
        # Complex code with low clarity
        complex_code = '''
def a(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z):
    if b:
        if c:
            if d:
                if e:
                    if f:
                        if g:
                            if h:
                                if i:
                                    if j:
                                        if k:
                                            return l(m(n(o(p(q(r(s(t(u(v(w(x(y(z))))))))))))))
'''
        
        result = await codex_skills.analyze_code(
            code=complex_code,
            analysis_type="maintainability",
            user_id="test_user"
        )
        
        # Should detect low clarity
        assert result["maintainability_score"] < 0.5  # Low maintainability due to complexity
    
    @pytest.mark.asyncio
    async def test_security_vulnerability_detection(self, codex_skills):
        """Test security vulnerability detection"""
        
        vulnerable_code = '''
def process_input(user_input):
    eval(user_input)  # Dangerous!
    return user_input
'''
        
        result = await codex_skills.analyze_code(
            code=vulnerable_code,
            analysis_type="security",
            user_id="test_user"
        )
        
        assert result["security_score"] < 0.8  # Should detect vulnerability
        assert len(result["asi_validation"]["security_issues"]) > 0
    
    @pytest.mark.asyncio
    async def test_trinity_coordination_in_generation(self, codex_skills):
        """Test trinity coordination in code generation"""
        
        result = await codex_skills.generate_code(
            requirements="Create a secure user authentication function",
            constraints=["Must use constitutional governance", "Must validate input", "Must handle errors"],
            user_id="test_user"
        )
        
        assert "trinity_validation" in result
        trinity_validation = result["trinity_validation"]
        assert isinstance(trinity_validation, dict)
        
        # Should have trinity coordination results
        if result["verdict"] in [CodeVerdict.CODE_SEAL.value, CodeVerdict.CODE_PARTIAL.value]:
            assert trinity_validation.get("agi_validation", False) or trinity_validation.get("agi_contribution", False)
            assert trinity_validation.get("asi_validation", False) or trinity_validation.get("asi_contribution", False)
            assert trinity_validation.get("apex_verdict", False) or trinity_validation.get("apex_contribution", False)


class TestTrinityCoordinator:
    """Test Trinity Coordinator"""
    
    @pytest.fixture
    def trinity_coordinator(self):
        """Create test Trinity coordinator"""
        return TrinityCoordinator(user_id="test_user")
    
    @pytest.mark.asyncio
    async def test_general_trinity_coordination(self, trinity_coordinator):
        """Test general trinity coordination"""
        
        task = "Design a secure user authentication system"
        context = {"domain": "web_application", "security_level": "high"}
        
        result = await trinity_coordinator.coordinate_trinity_operation(task, context)
        
        assert isinstance(result, TrinityResult)
        assert result.constitutional_verdict in [Verdict.SEAL, Verdict.PARTIAL, Verdict.VOID, Verdict.SABAR]
        assert result.geometric_integrity in [True, False]
        assert result.execution_time_ms > 0
        
        # Check all contributions are present
        assert result.agi_contribution is not None
        assert result.asi_contribution is not None
        assert result.apex_verdict is not None
        assert result.final_synthesis is not None
        assert len(result.final_synthesis) > 0
    
    @pytest.mark.asyncio
    async def test_codex_specific_trinity_synthesis(self, trinity_coordinator):
        """Test Codex-specific trinity synthesis"""
        
        coding_task = "Create a function to validate email addresses"
        requirements = "Must be secure, handle edge cases, and be readable"
        constraints = ["Must use constitutional governance", "Must validate input", "Must handle errors gracefully"]
        
        result = await trinity_coordinator.codex_specific_trinity_synthesis(
            coding_task=coding_task,
            requirements=requirements,
            constraints=constraints
        )
        
        assert isinstance(result, CodexTrinitySynthesis)
        assert result.constitutional_verdict in [Verdict.SEAL, Verdict.PARTIAL, Verdict.VOID, Verdict.SABAR]
        assert result.execution_time_ms > 0
        
        # Check all contributions are present
        assert result.architectural_foundation is not None
        assert result.safety_validation is not None
        assert result.code_solution is not None
        assert result.trinity_metrics is not None
    
    @pytest.mark.asyncio
    async def test_geometric_integrity_validation(self, trinity_coordinator):
        """Test geometric integrity validation"""
        
        task = "Design a simple API endpoint"
        
        result = await trinity_coordinator.coordinate_trinity_operation(task)
        
        # Geometric integrity should be validated
        assert isinstance(result.geometric_integrity, bool)
        
        # If successful, should maintain geometric separation
        if result.constitutional_verdict in [Verdict.SEAL, Verdict.PARTIAL]:
            # Check that each phase maintained its geometric role
            agi_contribution = result.agi_contribution
            asi_contribution = result.asi_contribution
            apex_contribution = result.apex_verdict
            
            # All should have constitutional compliance
            assert len(agi_contribution.constitutional_compliance) > 0
            assert len(asi_contribution.constitutional_compliance) > 0
            assert len(apex_contribution.constitutional_compliance) > 0
    
    @pytest.mark.asyncio
    async def test_constitutional_compliance_enforcement(self, trinity_coordinator):
        """Test constitutional compliance enforcement"""
        
        task = "Design a system that violates F2 Truth"
        
        result = await trinity_coordinator.coordinate_trinity_operation(task)
        
        # Should handle constitutional violations appropriately
        if result.constitutional_verdict == Verdict.VOID:
            assert "violation" in result.final_synthesis.lower() or len(result.final_synthesis) > 0
    
    @pytest.mark.asyncio
    async def test_consensus_threshold_enforcement(self, trinity_coordinator):
        """Test consensus threshold enforcement"""
        
        task = "Design a controversial system"
        
        # Test with consensus requirement
        result_with_consensus = await trinity_coordinator.coordinate_trinity_operation(
            task, require_consensus=True
        )
        
        # Test without consensus requirement
        result_without_consensus = await trinity_coordinator.coordinate_trinity_operation(
            task, require_consensus=False
        )
        
        # Results may differ based on consensus requirement
        assert result_with_consensus.trinity_metrics is not None
        assert result_without_consensus.trinity_metrics is not None


class TestCodexMCPIntegration:
    """Test complete Codex MCP integration"""
    
    @pytest.mark.asyncio
    async def test_end_to_end_constitutional_workflow(self):
        """Test end-to-end constitutional workflow"""
        
        # Simulate a complete constitutional coding workflow
        
        # 1. Code analysis request
        analysis_query = "Analyze this function for security: def process(data): return eval(data)"
        
        # 2. Constitutional processing through client
        client = ConstitutionalCodexClient(user_id="test_user")
        analysis_result = await client.process_constitutional_request(
            query=analysis_query,
            intent="code_analysis"
        )
        
        # 3. Verify constitutional compliance
        assert analysis_result.verdict in [Verdict.SEAL, Verdict.PARTIAL, Verdict.VOID, Verdict.SABAR]
        assert analysis_result.constitutional_compliance is not None
        
        # 4. Code generation request based on analysis
        if analysis_result.verdict in [Verdict.VOID, Verdict.SABAR]:
            generation_query = "Generate a secure alternative to eval() function"
            
            generation_result = await client.process_constitutional_request(
                query=generation_query,
                intent="code_generation"
            )
            
            assert generation_result.verdict in [Verdict.SEAL, Verdict.PARTIAL, Verdict.VOID, Verdict.SABAR]
    
    @pytest.mark.asyncio
    async def test_multi_agent_coordination(self):
        """Test multi-agent coordination through trinity"""
        
        # Create a task that requires trinity coordination
        complex_task = "Design a distributed system with high availability, security, and maintainability"
        
        coordinator = TrinityCoordinator(user_id="test_user")
        
        result = await coordinator.coordinate_trinity_operation(complex_task)
        
        # Verify trinity coordination
        assert result.agi_contribution is not None
        assert result.asi_contribution is not None
        assert result.apex_verdict is not None
        
        # Should have contributions from all three phases
        assert len(result.agi_contribution.contribution) > 0
        assert len(result.asi_contribution.contribution) > 0
        assert len(result.apex_verdict.contribution) > 0
        
        # Should have constitutional metrics
        assert len(result.trinity_metrics) > 0
        assert "consensus_score" in result.trinity_metrics or "agi_confidence" in result.trinity_metrics
    
    @pytest.mark.asyncio
    async def test_memory_integration(self):
        """Test VAULT-999 memory integration"""
        
        # Test storing and retrieving constitutional insights
        
        # Store a constitutional insight
        insight_text = "Constitutional insight: Always validate user input before processing"
        structure = "Input validation is now a constitutional requirement"
        truth_boundary = "All user inputs must be validated before processing"
        scar = "Discovered through security analysis of vulnerable code"
        
        # This would test vault999_store and vault999_query
        # For now, just verify the integration points exist
        from arifos_core.memory.vault999 import vault999_store, vault999_query
        
        assert vault999_store is not None
        assert vault999_query is not None
    
    @pytest.mark.asyncio
    async def test_error_handling_and_recovery(self):
        """Test error handling and constitutional recovery"""
        
        # Test with invalid inputs
        client = ConstitutionalCodexClient(user_id="test_user")
        
        # Invalid query
        invalid_result = await client.process_constitutional_request(
            query="",
            intent=""
        )
        
        assert invalid_result.verdict == Verdict.VOID
        assert len(invalid_result.reason) > 0
        
        # Malicious query
        malicious_result = await client.process_constitutional_request(
            query="eval('rm -rf /')",
            intent="execute"
        )
        
        assert malicious_result.verdict in [Verdict.VOID, Verdict.SABAR]
        assert "injection" in malicious_result.reason.lower() or len(malicious_result.reason) > 0


class TestConfigurationAndDeployment:
    """Test configuration and deployment scenarios"""
    
    def test_configuration_loading(self):
        """Test configuration loading"""
        
        # Test configuration with environment variables
        import os
        
        # Set test environment variables
        os.environ["ARIFOS_USER_ID"] = "test_config_user"
        os.environ["ARIFOS_CONSTITUTIONAL_MODE"] = "true"
        os.environ["ARIFOS_TRINITY_ENABLED"] = "true"
        
        from arifos_core.mcp.codex_server import CodexMCPServerConfig
        
        config = CodexMCPServerConfig()
        
        assert config.user_id == "test_config_user"
        assert config.constitutional_mode is True
        assert config.trinity_coordination is True
        
        # Clean up
        del os.environ["ARIFOS_USER_ID"]
        del os.environ["ARIFOS_CONSTITUTIONAL_MODE"]
        del os.environ["ARIFOS_TRINITY_ENABLED"]
    
    def test_tool_configuration(self):
        """Test tool configuration"""
        
        # Load configuration file
        import json
        
        config_path = "config/codex_mcp_config.json"
        try:
            with open(config_path, 'r') as f:
                config = json.load(f)
            
            # Verify tool configuration
            assert "enabledTools" in config["toolConfiguration"]
            assert "codex_code_analysis" in config["toolConfiguration"]["enabledTools"]
            assert "codex_code_generation" in config["toolConfiguration"]["enabledTools"]
            assert "arifos_live" in config["toolConfiguration"]["enabledTools"]
            
            # Verify constitutional settings
            assert "constitutionalSettings" in config
            assert "f4ClarityThreshold" in config["constitutionalSettings"]
            assert "consensusThreshold" in config["constitutionalSettings"]
            
        except FileNotFoundError:
            pytest.skip(f"Configuration file not found: {config_path}")
    
    @pytest.mark.asyncio
    async def test_performance_benchmarks(self):
        """Test performance benchmarks"""
        
        client = ConstitutionalCodexClient(user_id="test_user")
        
        # Benchmark constitutional request processing
        import time
        
        start_time = time.time()
        
        result = await client.process_constitutional_request(
            query="Generate a simple function to add two numbers",
            intent="code_generation"
        )
        
        end_time = time.time()
        
        # Performance requirements
        assert result.execution_time_ms < 5000  # Should complete within 5 seconds
        assert end_time - start_time < 10.0  # Total time should be reasonable
        
        # Constitutional reflex speed (should be < 8.7ms for reflexes)
        assert result.execution_time_ms > 0  # Should have measurable execution time


@pytest.mark.asyncio
async def test_integration_summary():
    """Summary test of all integration components"""
    
    print("=== Constitutional Codex MCP Integration Test Summary ===")
    
    # Test 1: Constitutional Client
    client = ConstitutionalCodexClient(user_id="integration_test")
    result = await client.process_constitutional_request(
        query="Test constitutional processing",
        intent="test"
    )
    
    print(f"✅ Constitutional Client: {result.verdict} verdict in {result.execution_time_ms:.1f}ms")
    
    # Test 2: Codex Skills
    skills = CodexConstitutionalSkills(user_id="integration_test")
    analysis_result = await skills.analyze_code(
        code="def test(): return True",
        analysis_type="maintainability",
        user_id="integration_test"
    )
    
    print(f"✅ Codex Skills: {analysis_result['verdict']} analysis with {len(analysis_result['agi_insights'])} AGI insights")
    
    # Test 3: Trinity Coordination
    coordinator = TrinityCoordinator(user_id="integration_test")
    trinity_result = await coordinator.coordinate_trinity_operation(
        task="Design a simple test system"
    )
    
    print(f"✅ Trinity Coordinator: {trinity_result.constitutional_verdict} verdict with {trinity_result.trinity_metrics.get('consensus_score', 0):.2f} consensus")
    
    # Test 4: Memory Integration
    from arifos_core.memory.vault999 import vault999_query, vault999_store
    
    print("✅ Memory Integration: VAULT-999 query and store functions available")
    
    # Test 5: Configuration
    import os
    config_available = os.path.exists("config/codex_mcp_config.json")
    
    print(f"✅ Configuration: {'Available' if config_available else 'Missing'}")
    
    print("\n🎯 All integration components tested successfully!")
    print("📊 Constitutional governance enforced across all tools")
    print("🔮 Trinity coordination functional for multi-agent synthesis")
    print("💾 Memory integration ready for constitutional storage")
    print("⚙️  Configuration system prepared for deployment")


if __name__ == "__main__":
    # Run tests
    pytest.main([__file__, "-v", "--tb=short"])