#!/usr/bin/env python3
"""
Demonstration of the Marsys logging system.

This example shows various features of the new logging system including:
- Three-tier logging levels
- Async-safe logging
- Context management
- Performance measurement
- Structured output
"""

import asyncio
import time
from marsys.logging import MarsysLogger, LogContext, LogConfig
from marsys.logging.utils import logged, LogCapture


# Get a logger instance
logger = MarsysLogger.get_logger("logging_demo")


class DemoAgent:
    """Example agent using the new logging system."""
    
    def __init__(self, name: str):
        self.name = name
        self.logger = MarsysLogger.get_logger(f"agent.{name}")
    
    @logged(level='detailed', include_result=True)
    async def process_task(self, task: str) -> dict:
        """Process a task with automatic logging."""
        # Set agent context
        LogContext.set_agent_name(self.name)
        
        # Log task start
        self.logger.detailed("task.started", task=task)
        
        # Simulate processing with timing
        async with self.logger.measure_async("task_processing"):
            await asyncio.sleep(0.1)  # Simulate work
            
            # Log intermediate step
            self.logger.debug("task.processing", 
                            step="validation",
                            task_length=len(task))
            
            result = {
                'status': 'success',
                'task': task,
                'agent': self.name,
                'processing_time': 0.1
            }
        
        # Log completion
        self.logger.detailed("task.completed", 
                           result_status=result['status'])
        
        return result


async def demonstrate_logging_levels():
    """Demonstrate the three logging levels."""
    print("\n" + "="*60)
    print("DEMONSTRATING LOGGING LEVELS")
    print("="*60)
    
    # Essential level - minimal logging
    logger.essential("service.started", 
                    service="marsys",
                    version="1.0.0")
    
    # Detailed level - operational insights
    logger.detailed("request.received",
                   method="POST",
                   path="/api/agents",
                   user_id="user-123")
    
    # Debug level - complete trace
    logger.debug("model.inference",
                prompt="Analyze this data",
                tokens_used=150,
                model="gpt-4",
                temperature=0.7)
    
    print("✓ Logged at all three levels")


async def demonstrate_context_management():
    """Demonstrate context management with correlation IDs."""
    print("\n" + "="*60)
    print("DEMONSTRATING CONTEXT MANAGEMENT")
    print("="*60)
    
    # Use correlation context
    with logger.correlate() as correlation_id:
        logger.detailed("workflow.started", 
                       workflow="data_processing")
        
        # Context automatically included in all logs
        LogContext.set_user_id("user-456")
        LogContext.set_session_id("session-789")
        
        # These logs will include correlation_id, user_id, session_id
        logger.detailed("step1.completed")
        logger.detailed("step2.completed")
        
        print(f"✓ All logs include correlation_id: {correlation_id}")


async def demonstrate_performance_measurement():
    """Demonstrate performance measurement features."""
    print("\n" + "="*60)
    print("DEMONSTRATING PERFORMANCE MEASUREMENT")
    print("="*60)
    
    # Measure synchronous operation
    with logger.measure_time("database_query"):
        time.sleep(0.05)  # Simulate DB query
    
    # Measure async operation
    async with logger.measure_async("api_call"):
        await asyncio.sleep(0.1)  # Simulate API call
    
    # Log custom metrics
    logger.metric("cache_hit_rate", 0.85, unit="ratio")
    logger.metric("response_time", 125.5, unit="ms", endpoint="/api/data")
    
    print("✓ Performance metrics logged")


async def demonstrate_multi_agent_workflow():
    """Demonstrate logging in a multi-agent workflow."""
    print("\n" + "="*60)
    print("DEMONSTRATING MULTI-AGENT WORKFLOW")
    print("="*60)
    
    # Create agents
    agent1 = DemoAgent("ResearchAgent")
    agent2 = DemoAgent("AnalysisAgent")
    
    # Set request context
    request_id = "req-12345"
    LogContext.set_request_id(request_id)
    
    # Orchestrate workflow
    logger.essential("workflow.started",
                    request_id=request_id,
                    agents=["ResearchAgent", "AnalysisAgent"])
    
    # Run agents in parallel
    tasks = [
        agent1.process_task("Research market trends"),
        agent2.process_task("Analyze competitor data")
    ]
    
    results = await asyncio.gather(*tasks)
    
    logger.essential("workflow.completed",
                    request_id=request_id,
                    success=all(r['status'] == 'success' for r in results))
    
    print(f"✓ Multi-agent workflow completed with request_id: {request_id}")


def demonstrate_error_handling():
    """Demonstrate error logging."""
    print("\n" + "="*60)
    print("DEMONSTRATING ERROR HANDLING")
    print("="*60)
    
    try:
        # Simulate an error
        raise ValueError("Invalid configuration parameter")
    except Exception as e:
        logger.error("configuration.error",
                    error_type=type(e).__name__,
                    error_message=str(e),
                    exc_info=True)
    
    print("✓ Error logged with traceback")


def demonstrate_log_capture():
    """Demonstrate log capture for testing."""
    print("\n" + "="*60)
    print("DEMONSTRATING LOG CAPTURE (FOR TESTING)")
    print("="*60)
    
    with LogCapture() as capture:
        logger.detailed("test.event", value=42)
        logger.essential("critical.event", alert=True)
    
    # Check captured logs
    assert capture.has_event("test.event")
    assert capture.has_event("critical.event")
    
    test_event = capture.get_event("test.event")
    assert test_event['value'] == 42
    
    print(f"✓ Captured {len(capture.events)} events for testing")


async def main():
    """Run all demonstrations."""
    print("\n" + "="*60)
    print("MARSYS LOGGING SYSTEM DEMONSTRATION")
    print("="*60)
    
    # Configure logging for demo
    config = LogConfig.from_env()
    MarsysLogger.configure(config=config)
    
    # Run demonstrations
    await demonstrate_logging_levels()
    await demonstrate_context_management()
    await demonstrate_performance_measurement()
    await demonstrate_multi_agent_workflow()
    demonstrate_error_handling()
    demonstrate_log_capture()
    
    print("\n" + "="*60)
    print("DEMONSTRATION COMPLETE")
    print("="*60)
    print("\nCheck logs/marsys.log for structured output")
    print("To see console output, set MARSYS_LOG_CONSOLE=true")
    
    # Cleanup
    MarsysLogger.shutdown()


if __name__ == "__main__":
    # Run with console output for demo
    import os
    os.environ['MARSYS_LOG_CONSOLE'] = 'true'
    os.environ['MARSYS_LOG_LEVEL'] = 'DEBUG'
    
    asyncio.run(main())