"""
监控和日志系统模块
负责实时监控服务器性能和记录日志
"""

import time
import threading
import json
import os
from typing import Dict, Any, List, Optional
from collections import deque

class MonitoringSystem:
    """
    监控系统
    负责实时监控服务器性能和记录日志
    """
    
    def __init__(self, plugin):
        """
        初始化监控系统
        
        Args:
            plugin: 服务器架构插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 监控配置
        self.monitoring_config = {
            "enable_monitoring": True,
            "monitoring_interval": 5.0,
            "log_level": "INFO",
            "enable_file_logging": True,
            "log_file_path": "/home/hello/EG/plugins/user/server_architecture/logs/server_monitor.log",
            "max_log_file_size": 10485760,  # 10MB
            "enable_performance_monitoring": True,
            "enable_alerts": True,
            "alert_thresholds": {
                "cpu_usage": 80.0,
                "memory_usage": 85.0,
                "disk_usage": 90.0,
                "network_latency": 100.0,
                "error_rate": 5.0
            },
            "enable_metrics_collection": True,
            "metrics_retention_period": 3600,  # 1小时
            "enable_realtime_dashboard": True
        }
        
        # 性能指标存储
        self.performance_metrics = {
            "cpu_usage": deque(maxlen=1000),
            "memory_usage": deque(maxlen=1000),
            "disk_usage": deque(maxlen=1000),
            "network_in": deque(maxlen=1000),
            "network_out": deque(maxlen=1000),
            "active_connections": deque(maxlen=1000),
            "requests_per_second": deque(maxlen=1000),
            "response_time": deque(maxlen=1000),
            "error_rate": deque(maxlen=1000)
        }
        
        # 监控状态
        self.monitoring_state = {
            "last_monitoring_update": 0.0,
            "last_performance_check": 0.0,
            "total_logs": 0,
            "total_alerts": 0,
            "active_alerts": 0
        }
        
        # 警报系统
        self.active_alerts = {}
        self.alert_history = deque(maxlen=1000)
        
        # 日志文件
        self.log_file = None
        self.log_file_size = 0
        
        # 监控统计
        self.monitoring_stats = {
            "metrics_collected": 0,
            "logs_written": 0,
            "alerts_generated": 0,
            "alerts_resolved": 0,
            "performance_checks": 0,
            "errors": 0
        }
        
        # 线程锁
        self.monitoring_lock = threading.RLock()
        
        # 回调函数
        self.monitoring_callbacks = {
            "metric_collected": [],
            "alert_triggered": [],
            "alert_resolved": [],
            "log_entry": [],
            "performance_degraded": []
        }
        
        # 监控线程
        self.monitoring_thread = None
        self.monitoring_thread_running = False
        
        # 时间戳记录
        self.last_log_write = 0.0
        self.last_metric_collection = 0.0
        
        print("✓ 监控系统已创建")
        
    def initialize(self) -> bool:
        """
        初始化监控系统
        
        Returns:
            是否初始化成功
        """
        try:
            print("正在初始化监控系统...")
            
            # 创建日志目录
            log_dir = os.path.dirname(self.monitoring_config["log_file_path"])
            if not os.path.exists(log_dir):
                os.makedirs(log_dir)
                
            # 初始化日志文件
            if self.monitoring_config["enable_file_logging"]:
                self._initialize_log_file()
                
            # 启动监控线程
            self._start_monitoring_thread()
            
            self.initialized = True
            print("✓ 监控系统初始化完成")
            return True
            
        except Exception as e:
            print(f"✗ 监控系统初始化失败: {e}")
            self.monitoring_stats["errors"] += 1
            import traceback
            traceback.print_exc()
            return False
            
    def _initialize_log_file(self):
        """初始化日志文件"""
        try:
            # 检查文件是否存在
            if os.path.exists(self.monitoring_config["log_file_path"]):
                self.log_file_size = os.path.getsize(self.monitoring_config["log_file_path"])
                
            # 打开日志文件
            self.log_file = open(self.monitoring_config["log_file_path"], "a", encoding="utf-8")
            print(f"✓ 日志文件已初始化: {self.monitoring_config['log_file_path']}")
            
        except Exception as e:
            print(f"✗ 日志文件初始化失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _start_monitoring_thread(self):
        """启动监控线程"""
        try:
            self.monitoring_thread_running = True
            self.monitoring_thread = threading.Thread(target=self._monitoring_loop, daemon=True)
            self.monitoring_thread.start()
            print("✓ 监控线程已启动")
        except Exception as e:
            print(f"✗ 监控线程启动失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _monitoring_loop(self):
        """监控线程循环"""
        try:
            while self.monitoring_thread_running:
                try:
                    if self.enabled and self.monitoring_config["enable_monitoring"]:
                        current_time = time.time()
                        
                        # 收集性能指标
                        if current_time - self.last_metric_collection >= self.monitoring_config["monitoring_interval"]:
                            self._collect_performance_metrics()
                            self.last_metric_collection = current_time
                            
                        # 检查警报
                        self._check_alerts()
                        
                        # 检查日志文件大小
                        self._check_log_file_size()
                        
                    # 短暂休眠
                    time.sleep(1.0)
                    
                except Exception as e:
                    print(f"✗ 监控循环错误: {e}")
                    self.monitoring_stats["errors"] += 1
                    time.sleep(5.0)  # 出错时延长休眠
                    
        except Exception as e:
            print(f"✗ 监控线程失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def enable(self) -> bool:
        """
        启用监控系统
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("✗ 监控系统未初始化")
                return False
                
            self.enabled = True
            print("✓ 监控系统已启用")
            return True
            
        except Exception as e:
            print(f"✗ 监控系统启用失败: {e}")
            self.monitoring_stats["errors"] += 1
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用监控系统"""
        try:
            self.enabled = False
            
            # 停止监控线程
            if self.monitoring_thread_running:
                self.monitoring_thread_running = False
                if self.monitoring_thread and self.monitoring_thread.is_alive():
                    self.monitoring_thread.join(timeout=5.0)
                    
            # 关闭日志文件
            if self.log_file:
                self.log_file.close()
                self.log_file = None
                
            print("✓ 监控系统已禁用")
            
        except Exception as e:
            print(f"✗ 监控系统禁用失败: {e}")
            self.monitoring_stats["errors"] += 1
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理监控系统资源"""
        try:
            # 禁用监控系统
            if self.enabled:
                self.disable()
                
            # 清理回调
            self.monitoring_callbacks.clear()
            
            self.initialized = False
            print("✓ 监控系统资源已清理")
            
        except Exception as e:
            print(f"✗ 监控系统资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新监控系统状态
        
        Args:
            dt: 时间增量（秒）
        """
        try:
            if not self.enabled:
                return
                
            current_time = time.time()
            self.monitoring_state["last_monitoring_update"] = current_time
            
        except Exception as e:
            print(f"✗ 监控系统更新失败: {e}")
            self.monitoring_stats["errors"] += 1
            import traceback
            traceback.print_exc()
            
    def _collect_performance_metrics(self):
        """收集性能指标"""
        try:
            current_time = time.time()
            metrics = {}
            
            # 收集系统资源使用情况
            try:
                import psutil
                
                # CPU使用率
                cpu_percent = psutil.cpu_percent(interval=0.1)
                metrics["cpu_usage"] = cpu_percent
                self.performance_metrics["cpu_usage"].append((current_time, cpu_percent))
                
                # 内存使用率
                memory_info = psutil.virtual_memory()
                memory_percent = memory_info.percent
                metrics["memory_usage"] = memory_percent
                self.performance_metrics["memory_usage"].append((current_time, memory_percent))
                
                # 磁盘使用率
                disk_info = psutil.disk_usage("/")
                disk_percent = (disk_info.used / disk_info.total) * 100
                metrics["disk_usage"] = disk_percent
                self.performance_metrics["disk_usage"].append((current_time, disk_percent))
                
                # 网络使用情况
                net_io = psutil.net_io_counters()
                metrics["network_in"] = net_io.bytes_recv
                metrics["network_out"] = net_io.bytes_sent
                self.performance_metrics["network_in"].append((current_time, net_io.bytes_recv))
                self.performance_metrics["network_out"].append((current_time, net_io.bytes_sent))
                
            except ImportError:
                # 如果没有psutil，使用简化的指标
                metrics["cpu_usage"] = 0.0
                metrics["memory_usage"] = 0.0
                metrics["disk_usage"] = 0.0
                metrics["network_in"] = 0
                metrics["network_out"] = 0
                
            # 收集服务器指标
            if self.plugin.server_manager:
                server_stats = self.plugin.server_manager.get_server_stats()
                server_state = server_stats.get("state", {})
                
                # 活跃连接数
                active_connections = server_state.get("current_connections", 0)
                metrics["active_connections"] = active_connections
                self.performance_metrics["active_connections"].append((current_time, active_connections))
                
                # 数据传输量
                bytes_sent = server_state.get("bytes_sent", 0)
                bytes_received = server_state.get("bytes_received", 0)
                metrics["bytes_sent"] = bytes_sent
                metrics["bytes_received"] = bytes_received
                
            # 收集客户端指标
            if self.plugin.client_manager:
                client_stats = self.plugin.client_manager.get_client_stats()
                client_count = client_stats.get("current_clients", 0)
                metrics["client_count"] = client_count
                
            # 收集消息指标
            if self.plugin.message_router:
                message_stats = self.plugin.message_router.get_message_stats()
                message_state = message_stats.get("stats", {})
                
                messages_received = message_state.get("messages_received", 0)
                messages_sent = message_state.get("messages_sent", 0)
                metrics["messages_received"] = messages_received
                metrics["messages_sent"] = messages_sent
                
                # 计算每秒请求数
                if hasattr(self, '_last_messages_received'):
                    rps = (messages_received - self._last_messages_received) / self.monitoring_config["monitoring_interval"]
                    metrics["requests_per_second"] = max(0, rps)
                    self.performance_metrics["requests_per_second"].append((current_time, metrics["requests_per_second"]))
                else:
                    metrics["requests_per_second"] = 0
                    self.performance_metrics["requests_per_second"].append((current_time, 0))
                    
                self._last_messages_received = messages_received
                
            # 收集房间指标
            if self.plugin.room_manager:
                room_stats = self.plugin.room_manager.get_room_stats()
                active_rooms = room_stats.get("current_rooms", 0)
                metrics["active_rooms"] = active_rooms
                
            # 更新统计
            self.monitoring_stats["metrics_collected"] += 1
            self.last_metric_collection = current_time
            
            # 触发指标收集回调
            self._trigger_monitoring_callback("metric_collected", {
                "metrics": metrics,
                "timestamp": current_time
            })
            
            # 记录日志
            if self._should_log("DEBUG"):
                self._write_log("DEBUG", f"性能指标收集: {metrics}")
                
        except Exception as e:
            print(f"✗ 性能指标收集失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _check_alerts(self):
        """检查警报条件"""
        try:
            if not self.monitoring_config["enable_alerts"]:
                return
                
            current_time = time.time()
            thresholds = self.monitoring_config["alert_thresholds"]
            
            # 检查CPU使用率
            if self.performance_metrics["cpu_usage"]:
                latest_cpu = self.performance_metrics["cpu_usage"][-1][1]
                if latest_cpu > thresholds["cpu_usage"]:
                    self._trigger_alert("high_cpu_usage", f"CPU使用率过高: {latest_cpu:.2f}%", current_time)
                    
            # 检查内存使用率
            if self.performance_metrics["memory_usage"]:
                latest_memory = self.performance_metrics["memory_usage"][-1][1]
                if latest_memory > thresholds["memory_usage"]:
                    self._trigger_alert("high_memory_usage", f"内存使用率过高: {latest_memory:.2f}%", current_time)
                    
            # 检查错误率
            if self.performance_metrics["error_rate"]:
                latest_error_rate = self.performance_metrics["error_rate"][-1][1]
                if latest_error_rate > thresholds["error_rate"]:
                    self._trigger_alert("high_error_rate", f"错误率过高: {latest_error_rate:.2f}%", current_time)
                    
            # 检查活跃连接数
            if self.performance_metrics["active_connections"]:
                latest_connections = self.performance_metrics["active_connections"][-1][1]
                if self.plugin.server_manager:
                    max_connections = self.plugin.server_manager.server_config.get("max_connections", 1000)
                    if latest_connections > max_connections * 0.9:  # 90%阈值
                        self._trigger_alert("high_connections", f"连接数接近上限: {latest_connections}/{max_connections}", current_time)
                        
        except Exception as e:
            print(f"✗ 警报检查失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _trigger_alert(self, alert_type: str, message: str, timestamp: float = None):
        """
        触发警报
        
        Args:
            alert_type: 警报类型
            message: 警报消息
            timestamp: 时间戳
        """
        try:
            if timestamp is None:
                timestamp = time.time()
                
            alert_id = f"{alert_type}_{int(timestamp)}"
            
            # 检查是否已存在相同类型的活动警报
            with self.monitoring_lock:
                if alert_type in self.active_alerts:
                    # 更新现有警报
                    self.active_alerts[alert_type]["count"] += 1
                    self.active_alerts[alert_type]["last_triggered"] = timestamp
                else:
                    # 创建新警报
                    self.active_alerts[alert_type] = {
                        "id": alert_id,
                        "type": alert_type,
                        "message": message,
                        "first_triggered": timestamp,
                        "last_triggered": timestamp,
                        "count": 1,
                        "resolved": False
                    }
                    
                    self.monitoring_state["active_alerts"] += 1
                    self.monitoring_stats["alerts_generated"] += 1
                    
                    # 添加到警报历史
                    self.alert_history.append({
                        "id": alert_id,
                        "type": alert_type,
                        "message": message,
                        "timestamp": timestamp,
                        "resolved": False
                    })
                    
                    # 触发警报回调
                    self._trigger_monitoring_callback("alert_triggered", {
                        "alert_id": alert_id,
                        "alert_type": alert_type,
                        "message": message,
                        "timestamp": timestamp
                    })
                    
                    # 记录日志
                    self._write_log("WARNING", f"警报触发 [{alert_type}]: {message}")
                    
        except Exception as e:
            print(f"✗ 警报触发失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def resolve_alert(self, alert_type: str):
        """
        解决警报
        
        Args:
            alert_type: 警报类型
        """
        try:
            with self.monitoring_lock:
                if alert_type in self.active_alerts:
                    alert_data = self.active_alerts[alert_type]
                    alert_data["resolved"] = True
                    alert_data["resolved_time"] = time.time()
                    
                    self.monitoring_state["active_alerts"] -= 1
                    self.monitoring_stats["alerts_resolved"] += 1
                    
                    # 触发警报解决回调
                    self._trigger_monitoring_callback("alert_resolved", {
                        "alert_type": alert_type,
                        "alert_data": alert_data
                    })
                    
                    # 从活动警报中移除
                    del self.active_alerts[alert_type]
                    
                    # 记录日志
                    self._write_log("INFO", f"警报已解决: {alert_type}")
                    
        except Exception as e:
            print(f"✗ 警报解决失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _check_log_file_size(self):
        """检查日志文件大小"""
        try:
            if not self.monitoring_config["enable_file_logging"] or not self.log_file:
                return
                
            # 检查文件大小
            if os.path.exists(self.monitoring_config["log_file_path"]):
                current_size = os.path.getsize(self.monitoring_config["log_file_path"])
                if current_size > self.monitoring_config["max_log_file_size"]:
                    # 轮转日志文件
                    self._rotate_log_file()
                    
        except Exception as e:
            print(f"✗ 日志文件大小检查失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _rotate_log_file(self):
        """轮转日志文件"""
        try:
            if self.log_file:
                self.log_file.close()
                
            # 重命名当前日志文件
            timestamp = int(time.time())
            rotated_filename = f"{self.monitoring_config['log_file_path']}.{timestamp}"
            os.rename(self.monitoring_config["log_file_path"], rotated_filename)
            
            # 重新初始化日志文件
            self._initialize_log_file()
            
            print(f"✓ 日志文件已轮转: {rotated_filename}")
            
        except Exception as e:
            print(f"✗ 日志文件轮转失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _write_log(self, level: str, message: str, extra_data: Dict[str, Any] = None):
        """
        写入日志
        
        Args:
            level: 日志级别
            message: 日志消息
            extra_data: 额外数据
        """
        try:
            if not self._should_log(level):
                return
                
            timestamp = time.time()
            log_entry = {
                "timestamp": timestamp,
                "level": level,
                "message": message,
                "extra_data": extra_data
            }
            
            # 控制台输出
            print(f"[{level}] {message}")
            
            # 文件日志
            if self.monitoring_config["enable_file_logging"] and self.log_file:
                try:
                    log_line = json.dumps(log_entry, ensure_ascii=False)
                    self.log_file.write(log_line + "\n")
                    self.log_file.flush()
                    
                    self.log_file_size += len(log_line) + 1
                    self.monitoring_stats["logs_written"] += 1
                    self.monitoring_state["total_logs"] += 1
                    
                except Exception as e:
                    print(f"✗ 文件日志写入失败: {e}")
                    
            # 触发日志条目回调
            self._trigger_monitoring_callback("log_entry", log_entry)
            
            self.last_log_write = timestamp
            
        except Exception as e:
            print(f"✗ 日志写入失败: {e}")
            self.monitoring_stats["errors"] += 1
            
    def _should_log(self, level: str) -> bool:
        """
        检查是否应该记录指定级别的日志
        
        Args:
            level: 日志级别
            
        Returns:
            是否应该记录日志
        """
        try:
            log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
            current_level = self.monitoring_config["log_level"]
            
            if current_level not in log_levels:
                return True  # 默认记录所有日志
                
            if level not in log_levels:
                return True  # 默认记录未知级别的日志
                
            current_index = log_levels.index(current_level)
            level_index = log_levels.index(level)
            
            # 只记录等于或高于当前级别的日志
            return level_index >= current_index
            
        except Exception as e:
            print(f"✗ 日志级别检查失败: {e}")
            return True
            
    def get_performance_metrics(self, metric_name: str = None, limit: int = 100) -> Any:
        """
        获取性能指标
        
        Args:
            metric_name: 指标名称（可选）
            limit: 限制返回的数量
            
        Returns:
            性能指标数据
        """
        try:
            with self.monitoring_lock:
                if metric_name:
                    if metric_name in self.performance_metrics:
                        metrics = list(self.performance_metrics[metric_name])
                        return metrics[-limit:] if len(metrics) > limit else metrics
                    else:
                        return []
                else:
                    # 返回所有指标
                    result = {}
                    for name, metrics in self.performance_metrics.items():
                        metric_list = list(metrics)
                        result[name] = metric_list[-limit:] if len(metric_list) > limit else metric_list
                    return result
                    
        except Exception as e:
            print(f"✗ 获取性能指标失败: {e}")
            self.monitoring_stats["errors"] += 1
            return {}
            
    def get_active_alerts(self) -> Dict[str, Any]:
        """
        获取活动警报
        
        Returns:
            活动警报字典
        """
        try:
            with self.monitoring_lock:
                return self.active_alerts.copy()
        except Exception as e:
            print(f"✗ 获取活动警报失败: {e}")
            self.monitoring_stats["errors"] += 1
            return {}
            
    def get_alert_history(self, limit: int = 100) -> List[Dict[str, Any]]:
        """
        获取警报历史
        
        Args:
            limit: 限制返回的数量
            
        Returns:
            警报历史列表
        """
        try:
            with self.monitoring_lock:
                history = list(self.alert_history)
                return history[-limit:] if len(history) > limit else history
        except Exception as e:
            print(f"✗ 获取警报历史失败: {e}")
            self.monitoring_stats["errors"] += 1
            return []
            
    def get_monitoring_stats(self) -> Dict[str, Any]:
        """
        获取监控统计信息
        
        Returns:
            监控统计字典
        """
        return {
            "state": self.monitoring_state.copy(),
            "stats": self.monitoring_stats.copy(),
            "config": self.monitoring_config.copy(),
            "active_alerts_count": len(self.active_alerts),
            "alert_history_count": len(self.alert_history)
        }
        
    def reset_stats(self):
        """重置监控统计信息"""
        try:
            self.monitoring_stats = {
                "metrics_collected": 0,
                "logs_written": 0,
                "alerts_generated": 0,
                "alerts_resolved": 0,
                "performance_checks": 0,
                "errors": 0
            }
            
            self.monitoring_state["total_logs"] = 0
            self.monitoring_state["total_alerts"] = 0
            self.monitoring_state["active_alerts"] = 0
            
            print("✓ 监控统计信息已重置")
        except Exception as e:
            print(f"✗ 监控统计信息重置失败: {e}")
            
    def set_monitoring_config(self, config: Dict[str, Any]) -> bool:
        """
        设置监控配置
        
        Args:
            config: 监控配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.monitoring_config.update(config)
            print(f"✓ 监控配置已更新: {self.monitoring_config}")
            return True
        except Exception as e:
            print(f"✗ 监控配置设置失败: {e}")
            return False
            
    def get_monitoring_config(self) -> Dict[str, Any]:
        """
        获取监控配置
        
        Returns:
            监控配置字典
        """
        return self.monitoring_config.copy()
        
    def _trigger_monitoring_callback(self, callback_type: str, data: Dict[str, Any]):
        """
        触发监控回调
        
        Args:
            callback_type: 回调类型
            data: 回调数据
        """
        try:
            if callback_type in self.monitoring_callbacks:
                for callback in self.monitoring_callbacks[callback_type]:
                    try:
                        callback(data)
                    except Exception as e:
                        print(f"✗ 监控回调执行失败: {callback_type} - {e}")
        except Exception as e:
            print(f"✗ 监控回调触发失败: {e}")
            
    def register_monitoring_callback(self, callback_type: str, callback: callable):
        """
        注册监控回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.monitoring_callbacks:
                self.monitoring_callbacks[callback_type].append(callback)
                print(f"✓ 监控回调已注册: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 监控回调注册失败: {e}")
            
    def unregister_monitoring_callback(self, callback_type: str, callback: callable):
        """
        注销监控回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.monitoring_callbacks:
                if callback in self.monitoring_callbacks[callback_type]:
                    self.monitoring_callbacks[callback_type].remove(callback)
                    print(f"✓ 监控回调已注销: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 监控回调注销失败: {e}")