#!/usr/bin/env python3
"""
Main server that runs both WebSocket OCPP server and FastAPI admin API
"""
import asyncio
import logging
import signal
import sys
import uvicorn
import platform
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from .config import get_config
from .websocket_server import WebSocketOCPPServer, connection_manager
from .admin import create_admin_app

# Configure logging
config = get_config()
logging.basicConfig(level=getattr(logging, config.log_level.upper()))
logger = logging.getLogger(__name__)


class OCPPServerWithAPI:
    """Combined OCPP WebSocket server and admin API"""
    
    def __init__(self):
        self.config = config
        self.websocket_server = WebSocketOCPPServer()
        self.admin_app = create_admin_app(connection_manager)
        self.api_server = None
        self._shutdown_event = asyncio.Event()
        
    async def start_servers(self):
        """Start both WebSocket and API servers"""
        try:
            logger.info("Starting OCPP WebSocket Server with Admin API...")
            
            # Start WebSocket server in background
            websocket_task = asyncio.create_task(self.websocket_server.start_server())
            
            # Start FastAPI server
            if self.config.admin_enabled:
                api_config = uvicorn.Config(
                    self.admin_app,
                    host=self.config.admin_host,
                    port=self.config.admin_port,
                    log_level=self.config.log_level.lower(),
                    access_log=False
                )
                self.api_server = uvicorn.Server(api_config)
                
                logger.info(f"Admin API available at http://{self.config.admin_host}:{self.config.admin_port}")
                logger.info(f"API Documentation: http://{self.config.admin_host}:{self.config.admin_port}/docs")
                
                # Start the API server task
                api_task = asyncio.create_task(self.api_server.serve())
                
                # Wait for shutdown signal
                await self._shutdown_event.wait()
                
                # Cancel server tasks
                websocket_task.cancel()
                api_task.cancel()
                
                try:
                    await websocket_task
                except asyncio.CancelledError:
                    pass
                    
                try:
                    await api_task
                except asyncio.CancelledError:
                    pass
            else:
                logger.info("Admin API is disabled")
                # Wait for shutdown signal
                await self._shutdown_event.wait()
                
                # Cancel WebSocket server task
                websocket_task.cancel()
                try:
                    await websocket_task
                except asyncio.CancelledError:
                    pass
                        
        except Exception as e:
            logger.error(f"Server startup failed: {e}")
            raise
    
    async def stop_servers(self):
        """Stop both servers gracefully"""
        logger.info("Stopping servers...")
        
        try:
            # Stop WebSocket server
            await self.websocket_server.stop_server()
            
            # Stop API server
            if self.api_server:
                self.api_server.should_exit = True
                
        except Exception as e:
            logger.error(f"Error during server shutdown: {e}")
        
        logger.info("Servers stopped")
    
    def signal_handler(self):
        """Handle shutdown signals"""
        logger.info("Received shutdown signal...")
        self._shutdown_event.set()


async def main():
    """Main function"""
    logger.info("Starting Voltie OCPP WebSocket Server with Admin API...")
    
    server = OCPPServerWithAPI()
    
    # Setup signal handlers (Windows compatible)
    loop = asyncio.get_running_loop()
    
    # Check if we're on Windows or Unix-like system
    if sys.platform == "win32":
        # Windows doesn't support add_signal_handler, use different approach
        logger.info("Windows detected - using Windows-compatible signal handling")
    else:
        # Unix-like systems can use add_signal_handler
        for sig in [signal.SIGINT, signal.SIGTERM]:
            if hasattr(signal, sig.name):
                loop.add_signal_handler(sig, server.signal_handler)
    
    try:
        await server.start_servers()
    except KeyboardInterrupt:
        logger.info("Received Ctrl+C, shutting down...")
    except Exception as e:
        logger.error(f"Server failed: {e}")
        raise
    finally:
        await server.stop_servers()


if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nGraceful shutdown complete.")
    except Exception as e:
        logger.error(f"Server failed: {e}")
        sys.exit(1)
