"""
Main entry point for rateloader application.

Final implementation with comprehensive startup sequence,
error handling, and graceful shutdown procedures.
Implements all PRD requirements and acceptance criteria.
"""

import sys
import os
import time
import signal
import traceback
from typing import Optional

# Add the current directory to Python path to import core modules
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from core.config import get_config
from core.logger import setup_logging, get_rateloader_logger, log_rateloader_info, log_rateloader_error, log_rateloader_exception
from core.task_queue import get_task_queue, start_task_queue, stop_task_queue
from core.scheduler import get_scheduler, start_scheduler, stop_scheduler
from core.http_server import get_http_server, start_server, stop_server


class RateLoaderApplication:
    """Main application class for rateloader with proper lifecycle management."""
    
    def __init__(self):
        """Initialize the application."""
        self.config = None
        self.logger_manager = None
        self.logger = None
        self.task_queue = None
        self.scheduler = None
        self.http_server = None
        self.running = False
        self.shutdown_requested = False
        
        # Set up signal handlers for graceful shutdown
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)
    
    def _signal_handler(self, signum, frame):
        """Handle shutdown signals."""
        print(f"\nReceived signal {signum}, initiating graceful shutdown...")
        self.shutdown_requested = True
        self.running = False
    
    def _initialize_configuration(self) -> bool:
        """Initialize configuration system."""
        try:
            print("Initializing configuration system...")
            self.config = get_config()
            print(f"✓ Configuration loaded from: {self.config.config_file}")
            
            # Display key configuration values
            print(f"  Oracle connection: {self.config.get('oracleconnectstring')}")
            print(f"  Server port: {self.config.get('server_port')}")
            print(f"  Schedule hours: {self.config.get_schedule_hours()}")
            
            return True
            
        except Exception as e:
            print(f"✗ Failed to initialize configuration: {str(e)}")
            return False
    
    def _initialize_logging(self) -> bool:
        """Initialize logging system."""
        try:
            print("Initializing logging system...")
            self.logger_manager = setup_logging()
            self.logger = get_rateloader_logger()
            
            print(f"✓ Logging initialized, directory: {self.logger_manager.log_dir}")
            
            # Test logging functionality
            log_rateloader_info("RateLoader application starting")
            log_rateloader_info("Configuration system initialized")
            log_rateloader_info("Logging system initialized")
            
            # Initialize other loggers
            from core.logger import (
                get_hotellabexport_logger,
                get_hotellabpriceexport_logger,
                log_hotellabexport_info,
                log_hotellabpriceexport_info,
            )
            
            log_hotellabexport_info("CSV/email export logger initialized")
            log_hotellabpriceexport_info("API export logger initialized")
            
            return True
            
        except Exception as e:
            print(f"✗ Failed to initialize logging: {str(e)}")
            return False
    
    def _start_task_queue(self) -> bool:
        """Start the task queue system."""
        try:
            print("Starting task queue...")
            self.task_queue = get_task_queue()
            
            if start_task_queue():
                print("✓ Task queue started successfully")
                log_rateloader_info("Task queue started successfully")
                return True
            else:
                print("✗ Failed to start task queue")
                log_rateloader_error("Failed to start task queue")
                return False
                
        except Exception as e:
            print(f"✗ Error starting task queue: {str(e)}")
            log_rateloader_exception("Error starting task queue", e)
            return False
    
    def _start_scheduler(self) -> bool:
        """Start the scheduler system."""
        try:
            print("Starting scheduler...")
            self.scheduler = get_scheduler()
            
            if start_scheduler():
                print("✓ Scheduler started successfully")
                log_rateloader_info("Scheduler started successfully")
                return True
            else:
                print("✗ Failed to start scheduler")
                log_rateloader_error("Failed to start scheduler")
                return False
                
        except Exception as e:
            print(f"✗ Error starting scheduler: {str(e)}")
            log_rateloader_exception("Error starting scheduler", e)
            return False
    
    def _start_http_server(self) -> bool:
        """Start the HTTP server."""
        try:
            print("Starting HTTP server...")
            self.http_server = get_http_server()
            
            if start_server():
                port = self.config.get_int('server_port', fallback=8000)
                print(f"✓ HTTP server started successfully on port {port}")
                log_rateloader_info(f"HTTP server started on port {port}")
                return True
            else:
                print("✗ Failed to start HTTP server")
                log_rateloader_error("Failed to start HTTP server")
                return False
                
        except Exception as e:
            print(f"✗ Error starting HTTP server: {str(e)}")
            log_rateloader_exception("Error starting HTTP server", e)
            return False
    
    def _validate_system_status(self) -> bool:
        """Validate that all systems are running properly."""
        try:
            print("Validating system status...")
            
            # Check task queue
            if not self.task_queue.is_running():
                print("✗ Task queue is not running")
                return False
            
            # Check scheduler
            if not self.scheduler.is_running():
                print("✗ Scheduler is not running")
                return False
            
            # Check HTTP server
            if not self.http_server.is_running:
                print("✗ HTTP server is not running")
                return False
            
            print("✓ All systems running properly")
            log_rateloader_info("All systems validated and running properly")
            return True
            
        except Exception as e:
            print(f"✗ Error validating system status: {str(e)}")
            log_rateloader_exception("Error validating system status", e)
            return False
    
    def _print_startup_info(self):
        """Print startup information and instructions."""
        print("\n" + "="*60)
        print("RateLoader v3.0 - All Systems Operational")
        print("="*60)
        print("\nFeatures:")
        print("• CSV export and email functionality")
        print("• JSON price export to API")
        print("• HTTP server for rate loading")
        print("• Automated task scheduling")
        print("• Comprehensive error handling")
        print("• Sequential task execution")
        print("\nConfiguration:")
        print(f"• Config file: {self.config.config_file}")
        print(f"• Log directory: {self.logger_manager.log_dir}")
        print(f"• HTTP port: {self.config.get_int('server_port', fallback=8000)}")
        print(f"• Schedule hours: {self.config.get_schedule_hours()}")
        print("\nHTTP Endpoints:")
        print("• GET  /ping   - Health check")
        print("• GET  /status - System status")
        print("• POST /load   - Rate data submission")
        print("\nGUI Mode:")
        print("• Run: python gui/app.py")
        print("• Provides manual control and monitoring")
        print("\nPress Ctrl+C to stop the application")
        print("="*60)
    
    def _cleanup(self):
        """Perform graceful shutdown cleanup."""
        print("\nInitiating graceful shutdown...")
        log_rateloader_info("Application shutdown initiated")
        
        cleanup_errors = []
        
        # Stop HTTP server
        try:
            print("Stopping HTTP server...")
            if stop_server():
                print("✓ HTTP server stopped")
                log_rateloader_info("HTTP server stopped successfully")
            else:
                print("⚠ HTTP server stop reported issues")
                log_rateloader_warning("HTTP server stop reported issues")
        except Exception as e:
            error_msg = f"Error stopping HTTP server: {str(e)}"
            print(f"✗ {error_msg}")
            log_rateloader_exception("Error stopping HTTP server", e)
            cleanup_errors.append(error_msg)
        
        # Stop scheduler
        try:
            print("Stopping scheduler...")
            if stop_scheduler():
                print("✓ Scheduler stopped")
                log_rateloader_info("Scheduler stopped successfully")
            else:
                print("⚠ Scheduler stop reported issues")
                log_rateloader_warning("Scheduler stop reported issues")
        except Exception as e:
            error_msg = f"Error stopping scheduler: {str(e)}"
            print(f"✗ {error_msg}")
            log_rateloader_exception("Error stopping scheduler", e)
            cleanup_errors.append(error_msg)
        
        # Stop task queue
        try:
            print("Stopping task queue...")
            if stop_task_queue():
                print("✓ Task queue stopped")
                log_rateloader_info("Task queue stopped successfully")
            else:
                print("⚠ Task queue stop reported issues")
                log_rateloader_warning("Task queue stop reported issues")
        except Exception as e:
            error_msg = f"Error stopping task queue: {str(e)}"
            print(f"✗ {error_msg}")
            log_rateloader_exception("Error stopping task queue", e)
            cleanup_errors.append(error_msg)
        
        # Final status
        if cleanup_errors:
            print(f"\n⚠ Shutdown completed with {len(cleanup_errors)} errors:")
            for error in cleanup_errors:
                print(f"  • {error}")
            log_rateloader_error(f"Shutdown completed with {len(cleanup_errors)} errors")
        else:
            print("\n✓ Application stopped gracefully")
            log_rateloader_info("Application stopped gracefully")
    
    def _main_loop(self):
        """Main application loop."""
        print("Application is running. Monitoring system health...")
        
        last_status_check = time.time()
        status_check_interval = 300  # Check every 5 minutes
        
        try:
            while self.running and not self.shutdown_requested:
                current_time = time.time()
                
                # Periodic status check
                if current_time - last_status_check >= status_check_interval:
                    if not self._validate_system_status():
                        print("⚠ System status check failed, attempting recovery...")
                        log_rateloader_warning("System status check failed, attempting recovery")
                        # Could add recovery logic here if needed
                    last_status_check = current_time
                
                # Sleep to prevent high CPU usage
                time.sleep(1)
                
        except KeyboardInterrupt:
            print("\nKeyboard interrupt received")
            self.shutdown_requested = True
        except Exception as e:
            print(f"\nUnexpected error in main loop: {str(e)}")
            log_rateloader_exception("Unexpected error in main loop", e)
            self.shutdown_requested = True
    
    def start(self) -> int:
        """Start the application."""
        print("RateLoader v3.0 - Starting...")
        print("="*60)
        
        # Initialize systems in order
        if not self._initialize_configuration():
            return 1
        
        if not self._initialize_logging():
            return 1
        
        if not self._start_task_queue():
            return 1
        
        if not self._start_scheduler():
            return 1
        
        if not self._start_http_server():
            return 1
        
        # Validate all systems
        if not self._validate_system_status():
            return 1
        
        # Print startup information
        self._print_startup_info()
        
        # Set running flag
        self.running = True
        
        # Log successful startup
        log_rateloader_info("RateLoader v3.0 started successfully")
        log_rateloader_info("All systems operational")
        
        try:
            # Run main loop
            self._main_loop()
            
            # Perform cleanup
            self._cleanup()
            
            return 0
            
        except Exception as e:
            print(f"Fatal error: {str(e)}")
            log_rateloader_exception("Fatal application error", e)
            self._cleanup()
            return 1


def main():
    """Main entry point for the rateloader application."""
    try:
        # Create and start application
        app = RateLoaderApplication()
        return app.start()
        
    except Exception as e:
        print(f"Fatal startup error: {str(e)}")
        print("\nFull traceback:")
        traceback.print_exc()
        return 1


if __name__ == "__main__":
    sys.exit(main())
