"""
Results collection and management system
"""

import json
import csv
import os
import logging
from datetime import datetime
from typing import List, Dict, Any
from src.testers.accessibility_tester import TestResult

class ResultsManager:
    """Manager for collecting and saving test results"""
    
    def __init__(self, config):
        self.config = config
        self.logger = logging.getLogger("results_manager")
        
        # Ensure results directory exists
        os.makedirs("results", exist_ok=True)
        os.makedirs("logs", exist_ok=True)
    
    def save_results(self, results: List[TestResult], stats: Dict[str, Any]) -> str:
        """Save test results to file"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        
        if self.config.output.format.lower() == "json":
            return self._save_json_results(results, stats, timestamp)
        elif self.config.output.format.lower() == "csv":
            return self._save_csv_results(results, stats, timestamp)
        else:
            # Default to JSON
            return self._save_json_results(results, stats, timestamp)
    
    def _save_json_results(self, results: List[TestResult], stats: Dict[str, Any], timestamp: str) -> str:
        """Save results in JSON format"""
        # Convert results to dictionaries
        results_data = []
        for result in results:
            results_data.append({
                'ip': result.ip,
                'provider': result.provider,
                'accessible': result.accessible,
                'response_time': result.response_time,
                'status_code': result.status_code,
                'error': result.error,
                'protocol': result.protocol
            })
        
        # Prepare complete data structure
        output_data = {
            'metadata': {
                'timestamp': timestamp,
                'total_tested': len(results),
                'total_accessible': sum(1 for r in results if r.accessible),
                'test_config': {
                    'concurrent_requests': self.config.performance.concurrent_requests,
                    'request_timeout': self.config.performance.request_timeout,
                    'batch_size': self.config.performance.batch_size,
                    'protocols': self.config.testing.protocols
                }
            },
            'statistics': stats,
            'results': results_data
        }
        
        # Save to file
        filename = f"accessibility_results_{timestamp}.json"
        filepath = os.path.join("results", filename)
        
        try:
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(output_data, f, indent=2, ensure_ascii=False)
            
            self.logger.info(f"Results saved to {filepath}")
            return filepath
            
        except Exception as e:
            self.logger.error(f"Error saving JSON results: {e}")
            return ""
    
    def _save_csv_results(self, results: List[TestResult], stats: Dict[str, Any], timestamp: str) -> str:
        """Save results in CSV format"""
        filename = f"accessibility_results_{timestamp}.csv"
        filepath = os.path.join("results", filename)
        
        try:
            with open(filepath, 'w', newline='', encoding='utf-8') as f:
                writer = csv.writer(f)
                
                # Write header
                writer.writerow([
                    'IP', 'Provider', 'Accessible', 'Response_Time', 
                    'Status_Code', 'Error', 'Protocol'
                ])
                
                # Write data
                for result in results:
                    writer.writerow([
                        result.ip,
                        result.provider,
                        result.accessible,
                        result.response_time,
                        result.status_code or '',
                        result.error or '',
                        result.protocol
                    ])
            
            # Also save statistics as separate JSON file
            stats_filename = f"statistics_{timestamp}.json"
            stats_filepath = os.path.join("results", stats_filename)
            
            with open(stats_filepath, 'w', encoding='utf-8') as f:
                json.dump(stats, f, indent=2, ensure_ascii=False)
            
            self.logger.info(f"Results saved to {filepath}")
            self.logger.info(f"Statistics saved to {stats_filepath}")
            return filepath
            
        except Exception as e:
            self.logger.error(f"Error saving CSV results: {e}")
            return ""
    
    def save_accessible_ips_only(self, results: List[TestResult]) -> str:
        """Save only accessible IPs in a simple format"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"accessible_ips_{timestamp}.txt"
        filepath = os.path.join("results", filename)
        
        try:
            # Group accessible IPs by provider
            accessible_by_provider = {}
            for result in results:
                if result.accessible:
                    if result.provider not in accessible_by_provider:
                        accessible_by_provider[result.provider] = []
                    accessible_by_provider[result.provider].append(result.ip)
            
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write(f"# Accessible CDN IPs - Generated on {datetime.now().isoformat()}\n")
                f.write(f"# Total accessible IPs: {sum(len(ips) for ips in accessible_by_provider.values())}\n\n")
                
                for provider, ips in accessible_by_provider.items():
                    f.write(f"# {provider.upper()} - {len(ips)} accessible IPs\n")
                    for ip in sorted(ips):
                        f.write(f"{ip}\n")
                    f.write("\n")
            
            self.logger.info(f"Accessible IPs saved to {filepath}")
            return filepath
            
        except Exception as e:
            self.logger.error(f"Error saving accessible IPs: {e}")
            return ""
    
    def save_provider_specific_results(self, results: List[TestResult]) -> Dict[str, str]:
        """Save results separated by provider"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        saved_files = {}
        
        # Group results by provider
        results_by_provider = {}
        for result in results:
            if result.provider not in results_by_provider:
                results_by_provider[result.provider] = []
            results_by_provider[result.provider].append(result)
        
        # Save each provider's results
        for provider, provider_results in results_by_provider.items():
            filename = f"{provider}_results_{timestamp}.json"
            filepath = os.path.join("results", filename)
            
            try:
                # Calculate provider-specific stats
                accessible_count = sum(1 for r in provider_results if r.accessible)
                avg_response_time = sum(r.response_time for r in provider_results) / len(provider_results)
                
                provider_data = {
                    'provider': provider,
                    'timestamp': timestamp,
                    'total_tested': len(provider_results),
                    'total_accessible': accessible_count,
                    'success_rate': accessible_count / len(provider_results),
                    'avg_response_time': avg_response_time,
                    'accessible_ips': [r.ip for r in provider_results if r.accessible],
                    'detailed_results': [
                        {
                            'ip': r.ip,
                            'accessible': r.accessible,
                            'response_time': r.response_time,
                            'status_code': r.status_code,
                            'error': r.error,
                            'protocol': r.protocol
                        } for r in provider_results
                    ]
                }
                
                with open(filepath, 'w', encoding='utf-8') as f:
                    json.dump(provider_data, f, indent=2, ensure_ascii=False)
                
                saved_files[provider] = filepath
                self.logger.info(f"{provider} results saved to {filepath}")
                
            except Exception as e:
                self.logger.error(f"Error saving {provider} results: {e}")
        
        return saved_files
    
    def load_previous_results(self, filepath: str) -> List[TestResult]:
        """Load previous test results from file"""
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            results = []
            for result_data in data.get('results', []):
                result = TestResult(
                    ip=result_data['ip'],
                    provider=result_data['provider'],
                    accessible=result_data['accessible'],
                    response_time=result_data['response_time'],
                    status_code=result_data.get('status_code'),
                    error=result_data.get('error'),
                    protocol=result_data.get('protocol', 'http')
                )
                results.append(result)
            
            self.logger.info(f"Loaded {len(results)} previous results from {filepath}")
            return results
            
        except Exception as e:
            self.logger.error(f"Error loading previous results: {e}")
            return []
    
    def generate_summary_report(self, results: List[TestResult], stats: Dict[str, Any]) -> str:
        """Generate a human-readable summary report"""
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"summary_report_{timestamp}.txt"
        filepath = os.path.join("results", filename)
        
        try:
            with open(filepath, 'w', encoding='utf-8') as f:
                f.write("=" * 60 + "\n")
                f.write("CDN IP ACCESSIBILITY TEST SUMMARY REPORT\n")
                f.write("=" * 60 + "\n")
                f.write(f"Generated: {datetime.now().isoformat()}\n\n")
                
                # Overall statistics
                f.write("OVERALL STATISTICS:\n")
                f.write("-" * 20 + "\n")
                f.write(f"Total IPs Tested: {stats['total_tested']}\n")
                f.write(f"Total Accessible: {stats['total_accessible']}\n")
                f.write(f"Overall Success Rate: {stats['total_accessible']/stats['total_tested']*100:.2f}%\n")
                f.write(f"Average Response Time: {stats['avg_response_time']:.3f}s\n\n")
                
                # Provider breakdown
                f.write("PROVIDER BREAKDOWN:\n")
                f.write("-" * 20 + "\n")
                for provider, provider_stats in stats['by_provider'].items():
                    f.write(f"{provider.upper()}:\n")
                    f.write(f"  Tested: {provider_stats['tested']}\n")
                    f.write(f"  Accessible: {provider_stats['accessible']}\n")
                    f.write(f"  Success Rate: {provider_stats['success_rate']*100:.2f}%\n\n")
                
                # Protocol usage
                if stats.get('protocols_used'):
                    f.write("PROTOCOL USAGE:\n")
                    f.write("-" * 15 + "\n")
                    for protocol, count in stats['protocols_used'].items():
                        f.write(f"{protocol.upper()}: {count} successful connections\n")
                    f.write("\n")
                
                # Top accessible IPs per provider (first 10)
                accessible_by_provider = {}
                for result in results:
                    if result.accessible:
                        if result.provider not in accessible_by_provider:
                            accessible_by_provider[result.provider] = []
                        accessible_by_provider[result.provider].append(result.ip)
                
                f.write("SAMPLE ACCESSIBLE IPs (First 10 per provider):\n")
                f.write("-" * 45 + "\n")
                for provider, ips in accessible_by_provider.items():
                    f.write(f"{provider.upper()}:\n")
                    for ip in sorted(ips)[:10]:
                        f.write(f"  {ip}\n")
                    if len(ips) > 10:
                        f.write(f"  ... and {len(ips) - 10} more\n")
                    f.write("\n")
            
            self.logger.info(f"Summary report saved to {filepath}")
            return filepath
            
        except Exception as e:
            self.logger.error(f"Error generating summary report: {e}")
            return ""