"""
BestCDN - High-performance CDN IP accessibility tester
Main orchestration script
"""

import asyncio
import logging
import sys
import os
from datetime import datetime
from typing import Dict

# Add src to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))

from config import Config
from src.utils.ip_reader import IPListReader
from src.testers.accessibility_tester import AccessibilityTester
from src.utils.results_manager import ResultsManager

class BestCDN:
    """Main BestCDN application class"""
    
    def __init__(self, config_file: str = "config.json"):
        self.config = Config(config_file)
        self.logger = self._setup_logging()
        self.ip_reader = IPListReader()
        self.results_manager = ResultsManager(self.config)
        
    def _setup_logging(self) -> logging.Logger:
        """Setup logging configuration"""
        # Create logs directory if it doesn't exist
        os.makedirs("logs", exist_ok=True)
        
        # Configure logging
        log_level = getattr(logging, self.config.output.log_level.upper(), logging.INFO)
        
        # Create formatter
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        
        # Setup file handler
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        log_file = os.path.join("logs", f"bestcdn_{timestamp}.log")
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setLevel(log_level)
        file_handler.setFormatter(formatter)
        
        # Setup console handler
        console_handler = logging.StreamHandler()
        console_handler.setLevel(log_level)
        console_handler.setFormatter(formatter)
        
        # Configure root logger
        root_logger = logging.getLogger()
        root_logger.setLevel(log_level)
        root_logger.addHandler(file_handler)
        root_logger.addHandler(console_handler)
        
        # Return main logger
        logger = logging.getLogger("bestcdn")
        logger.info(f"Logging initialized - Log file: {log_file}")
        
        return logger
    
    def validate_setup(self) -> bool:
        """Validate that everything is set up correctly"""
        self.logger.info("Validating setup...")
        
        # Check enabled providers
        enabled_providers = list(self.config.get_enabled_providers().keys())
        if not enabled_providers:
            self.logger.error("No CDN providers are enabled in configuration")
            return False
        
        self.logger.info(f"Enabled providers: {', '.join(enabled_providers)}")
        
        # Validate IP list files
        validation_results = self.ip_reader.validate_ip_lists(enabled_providers)
        
        missing_files = []
        for provider, result in validation_results.items():
            if not result['exists']:
                missing_files.append(provider)
            elif not result['readable']:
                self.logger.error(f"IP list file for {provider} is not readable")
                return False
            elif result['ip_count'] == 0:
                self.logger.warning(f"No valid IPs found in {provider} IP list")
            else:
                self.logger.info(f"{provider}: {result['ip_count']} IPs available")
        
        if missing_files:
            self.logger.error(f"Missing IP list files for: {', '.join(missing_files)}")
            self.logger.error("Please create the following files in the 'ip_lists' directory:")
            for provider in missing_files:
                self.logger.error(f"  - ip_lists/{provider}.txt")
            return False
        
        # Check test domains
        missing_domains = []
        for provider in enabled_providers:
            if not self.config.cdn_providers[provider].test_domain:
                missing_domains.append(provider)
        
        if missing_domains:
            self.logger.error(f"Missing test domains for: {', '.join(missing_domains)}")
            self.logger.error("Please set test domains using set_test_domain() or configuration")
            return False
        
        self.logger.info("Setup validation completed successfully")
        return True
    
    def set_test_domains(self, domains: Dict[str, str]):
        """Set test domains for providers"""
        for provider, domain in domains.items():
            if provider in self.config.cdn_providers:
                self.config.set_test_domain(provider, domain)
                self.logger.info(f"Set test domain for {provider}: {domain}")
            else:
                self.logger.warning(f"Unknown provider: {provider}")
    
    async def run_accessibility_test(self) -> bool:
        """Run the main accessibility test"""
        try:
            self.logger.info("=" * 60)
            self.logger.info("STARTING BESTCDN IP ACCESSIBILITY TEST")
            self.logger.info("=" * 60)
            
            # Load IP lists
            self.logger.info("Loading IP lists...")
            enabled_providers = list(self.config.get_enabled_providers().keys())
            provider_ips = self.ip_reader.read_all_ip_lists(enabled_providers)
            
            if not provider_ips:
                self.logger.error("No IP lists loaded successfully")
                return False
            
            # Prepare test domains
            test_domains = {}
            for provider in enabled_providers:
                test_domains[provider] = self.config.cdn_providers[provider].test_domain
            
            # Run accessibility tests
            self.logger.info("Starting accessibility tests...")
            async with AccessibilityTester(self.config) as tester:
                results = await tester.test_all_ips(provider_ips, test_domains)
                stats = tester.get_statistics()
            
            # Save results
            self.logger.info("Saving results...")
            
            # Save main results file
            main_results_file = self.results_manager.save_results(results, stats)
            if main_results_file:
                self.logger.info(f"Main results saved to: {main_results_file}")
            
            # Save accessible IPs only
            accessible_file = self.results_manager.save_accessible_ips_only(results)
            if accessible_file:
                self.logger.info(f"Accessible IPs saved to: {accessible_file}")
            
            # Save provider-specific results
            provider_files = self.results_manager.save_provider_specific_results(results)
            for provider, filepath in provider_files.items():
                self.logger.info(f"{provider} results saved to: {filepath}")
            
            # Generate summary report
            summary_file = self.results_manager.generate_summary_report(results, stats)
            if summary_file:
                self.logger.info(f"Summary report saved to: {summary_file}")
            
            # Log final statistics
            self.logger.info("=" * 60)
            self.logger.info("TEST COMPLETED SUCCESSFULLY")
            self.logger.info("=" * 60)
            self.logger.info(f"Total IPs tested: {stats['total_tested']}")
            self.logger.info(f"Total accessible: {stats['total_accessible']}")
            self.logger.info(f"Overall success rate: {stats['total_accessible']/stats['total_tested']*100:.2f}%")
            self.logger.info(f"Average response time: {stats['avg_response_time']:.3f}s")
            
            for provider, provider_stats in stats['by_provider'].items():
                self.logger.info(f"{provider}: {provider_stats['accessible']}/{provider_stats['tested']} "
                               f"({provider_stats['success_rate']*100:.2f}%)")
            
            return True
            
        except Exception as e:
            self.logger.error(f"Error during accessibility test: {e}", exc_info=True)
            return False
    
    def print_usage_info(self):
        """Print usage information"""
        print("\n" + "=" * 60)
        print("BestCDN - High-Performance CDN IP Accessibility Tester")
        print("=" * 60)
        print("\nBefore running, please ensure:")
        print("1. Create 'ip_lists' directory")
        print("2. Add IP list files for each provider:")
        
        enabled_providers = list(self.config.get_enabled_providers().keys())
        for provider in enabled_providers:
            print(f"   - ip_lists/{provider}.txt")
        
        print("3. Set test domains for each provider")
        print("\nExample usage:")
        print("```python")
        print("from src.main import BestCDN")
        print("")
        print("# Create BestCDN instance")
        print("app = BestCDN()")
        print("")
        print("# Set test domains")
        print("app.set_test_domains({")
        for provider in enabled_providers:
            print(f"    '{provider}': 'your-test-domain.com',")
        print("})")
        print("")
        print("# Run the test")
        print("import asyncio")
        print("asyncio.run(app.run_accessibility_test())")
        print("```")
        print("\n" + "=" * 60)

async def main():
    """Main entry point"""
    app = BestCDN()
    
    # Print usage info if setup is not valid
    if not app.validate_setup():
        app.print_usage_info()
        return False
    
    # Run the accessibility test
    success = await app.run_accessibility_test()
    return success

if __name__ == "__main__":
    try:
        success = asyncio.run(main())
        sys.exit(0 if success else 1)
    except KeyboardInterrupt:
        print("\nTest interrupted by user")
        sys.exit(1)
    except Exception as e:
        print(f"Unexpected error: {e}")
        sys.exit(1)