"""
连接管理器模块
负责管理网络连接和客户端状态
"""

import time
from typing import Dict, Any, List, Optional
import threading
import socket

class ConnectionManager:
    """
    连接管理器
    负责管理网络连接和客户端状态
    """
    
    def __init__(self, plugin):
        """
        初始化连接管理器
        
        Args:
            plugin: 网络同步插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 连接配置
        self.connection_config = {
            'max_connections': 32,
            'connection_timeout': 30.0,
            'reconnect_attempts': 3,
            'reconnect_interval': 5.0,
            'heartbeat_interval': 5.0,
            'enable_auto_reconnect': True,
            'enable_connection_limits': True,
            'max_connections_per_ip': 5
        }
        
        # 客户端管理
        self.clients = {}  # 已连接的客户端
        self.pending_connections = {}  # 待处理的连接
        self.banned_ips = set()  # 被禁止的IP地址
        
        # 服务器状态
        self.server_state = {
            'is_running': False,
            'port': 7777,
            'clients_connected': 0,
            'peak_connections': 0,
            'bytes_sent': 0,
            'bytes_received': 0
        }
        
        # 客户端状态
        self.client_state = {
            'is_connected': False,
            'server_address': '',
            'server_port': 7777,
            'connection_time': 0.0,
            'last_heartbeat': 0.0,
            'reconnect_attempts': 0
        }
        
        # 连接统计
        self.connection_stats = {
            'connections_accepted': 0,
            'connections_rejected': 0,
            'connections_lost': 0,
            'connections_timed_out': 0,
            'reconnections': 0,
            'banned_connections': 0
        }
        
        # 线程管理
        self.connection_thread = None
        self.heartbeat_thread = None
        self.reconnect_thread = None
        self.running = False
        
        # 回调函数
        self.connection_callbacks = {
            'client_connected': [],
            'client_disconnected': [],
            'connection_timeout': [],
            'reconnect_attempt': [],
            'connection_banned': []
        }
        
        # 时间戳记录
        self.last_connection_check = 0.0
        self.last_heartbeat_check = 0.0
        self.last_reconnect_attempt = 0.0
        
        print("✓ 连接管理器已创建")
        
    def initialize(self) -> bool:
        """
        初始化连接管理器
        
        Returns:
            是否初始化成功
        """
        try:
            self.initialized = True
            print("✓ 连接管理器初始化完成")
            return True
            
        except Exception as e:
            print(f"✗ 连接管理器初始化失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def enable(self) -> bool:
        """
        启用连接管理器
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("✗ 连接管理器未初始化")
                return False
                
            self.enabled = True
            self.running = True
            
            print("✓ 连接管理器已启用")
            return True
            
        except Exception as e:
            print(f"✗ 连接管理器启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用连接管理器"""
        try:
            self.enabled = False
            self.running = False
            
            # 断开所有连接
            self._disconnect_all_clients()
            self._disconnect_from_server()
            
            print("✓ 连接管理器已禁用")
            
        except Exception as e:
            print(f"✗ 连接管理器禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理连接管理器资源"""
        try:
            self.disable()
            self.clients.clear()
            self.pending_connections.clear()
            self.banned_ips.clear()
            self.connection_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()
            
            # 检查连接超时
            if current_time - self.last_connection_check >= 1.0:  # 每秒检查一次
                self._check_connection_timeouts(current_time)
                self.last_connection_check = current_time
                
            # 检查心跳超时
            if current_time - self.last_heartbeat_check >= self.connection_config['heartbeat_interval']:
                self._check_heartbeat_timeouts(current_time)
                self.last_heartbeat_check = current_time
                
        except Exception as e:
            print(f"✗ 连接管理器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _check_connection_timeouts(self, current_time: float):
        """
        检查连接超时
        
        Args:
            current_time: 当前时间
        """
        try:
            timeout_clients = []
            for client_id, client_data in self.clients.items():
                connect_time = client_data.get('connect_time', 0)
                if current_time - connect_time > self.connection_config['connection_timeout']:
                    timeout_clients.append(client_id)
                    
            for client_id in timeout_clients:
                self._disconnect_client(client_id, "timeout")
                self.connection_stats['connections_timed_out'] += 1
                
                # 触发连接超时回调
                self._trigger_connection_callback('connection_timeout', {
                    'client_id': client_id,
                    'reason': 'timeout'
                })
                
        except Exception as e:
            print(f"✗ 连接超时检查失败: {e}")
            
    def _check_heartbeat_timeouts(self, current_time: float):
        """
        检查心跳超时
        
        Args:
            current_time: 当前时间
        """
        try:
            timeout_clients = []
            for client_id, client_data in self.clients.items():
                last_heartbeat = client_data.get('last_heartbeat', 0)
                if current_time - last_heartbeat > self.connection_config['heartbeat_interval'] * 3:
                    timeout_clients.append(client_id)
                    
            for client_id in timeout_clients:
                self._disconnect_client(client_id, "heartbeat_timeout")
                
        except Exception as e:
            print(f"✗ 心跳超时检查失败: {e}")
            
    def connect_to_server(self, host: str, port: int = None) -> bool:
        """
        连接到服务器
        
        Args:
            host: 服务器地址
            port: 服务器端口
            
        Returns:
            是否连接成功
        """
        try:
            if self.client_state['is_connected']:
                print("✗ 客户端已连接到服务器")
                return False
                
            if port is None:
                port = self.connection_config['server_port']
                
            # 更新客户端状态
            self.client_state['server_address'] = host
            self.client_state['server_port'] = port
            self.client_state['connection_time'] = time.time()
            self.client_state['reconnect_attempts'] = 0
            
            # 通过网络管理器连接
            if self.plugin.network_manager:
                success = self.plugin.network_manager.connect_to_server(host, port)
                if success:
                    self.client_state['is_connected'] = True
                    print(f"✓ 已连接到服务器: {host}:{port}")
                    return True
                else:
                    print("✗ 连接服务器失败")
                    return False
            else:
                print("✗ 网络管理器未初始化")
                return False
                
        except Exception as e:
            print(f"✗ 连接服务器失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disconnect_from_server(self):
        """断开与服务器的连接"""
        try:
            self._disconnect_from_server()
            print("✓ 已断开与服务器的连接")
        except Exception as e:
            print(f"✗ 断开服务器连接失败: {e}")
            
    def _disconnect_from_server(self):
        """内部方法：断开与服务器的连接"""
        try:
            if self.plugin.network_manager:
                self.plugin.network_manager.disconnect_client()
                
            self.client_state['is_connected'] = False
            self.client_state['server_address'] = ''
            self.client_state['connection_time'] = 0.0
            
        except Exception as e:
            print(f"✗ 服务器断开连接失败: {e}")
            
    def add_client(self, client_id: str, client_socket: socket.socket, 
                   client_address: tuple) -> bool:
        """
        添加客户端连接
        
        Args:
            client_id: 客户端ID
            client_socket: 客户端套接字
            client_address: 客户端地址
            
        Returns:
            是否添加成功
        """
        try:
            client_ip = client_address[0]
            
            # 检查IP是否被禁止
            if client_ip in self.banned_ips:
                self.connection_stats['banned_connections'] += 1
                client_socket.close()
                
                # 触发连接禁止回调
                self._trigger_connection_callback('connection_banned', {
                    'client_id': client_id,
                    'ip': client_ip,
                    'address': client_address
                })
                
                return False
                
            # 检查连接限制
            if self.connection_config['enable_connection_limits']:
                ip_connections = sum(1 for client in self.clients.values() 
                                   if client.get('address', ('', 0))[0] == client_ip)
                if ip_connections >= self.connection_config['max_connections_per_ip']:
                    self.connection_stats['connections_rejected'] += 1
                    client_socket.close()
                    return False
                    
            # 检查最大连接数
            if (self.connection_config['enable_connection_limits'] and 
                len(self.clients) >= self.connection_config['max_connections']):
                self.connection_stats['connections_rejected'] += 1
                client_socket.close()
                return False
                
            # 添加客户端
            self.clients[client_id] = {
                'socket': client_socket,
                'address': client_address,
                'connect_time': time.time(),
                'last_heartbeat': time.time(),
                'bytes_sent': 0,
                'bytes_received': 0,
                'ping': 0.0
            }
            
            # 更新服务器状态
            self.server_state['clients_connected'] = len(self.clients)
            if len(self.clients) > self.server_state['peak_connections']:
                self.server_state['peak_connections'] = len(self.clients)
                
            self.connection_stats['connections_accepted'] += 1
            
            # 触发客户端连接回调
            self._trigger_connection_callback('client_connected', {
                'client_id': client_id,
                'address': client_address
            })
            
            print(f"✓ 客户端已连接: {client_id} ({client_address})")
            return True
            
        except Exception as e:
            print(f"✗ 添加客户端失败: {e}")
            self.connection_stats['connections_rejected'] += 1
            return False
            
    def remove_client(self, client_id: str, reason: str = "unknown"):
        """
        移除客户端连接
        
        Args:
            client_id: 客户端ID
            reason: 断开原因
        """
        try:
            if client_id in self.clients:
                client_data = self.clients[client_id]
                
                # 关闭套接字
                try:
                    client_data['socket'].close()
                except Exception as e:
                    pass
                    
                # 移除客户端
                del self.clients[client_id]
                
                # 更新服务器状态
                self.server_state['clients_connected'] = len(self.clients)
                
                self.connection_stats['connections_lost'] += 1
                
                # 触发客户端断开连接回调
                self._trigger_connection_callback('client_disconnected', {
                    'client_id': client_id,
                    'reason': reason
                })
                
                print(f"✓ 客户端已断开: {client_id} (原因: {reason})")
                
        except Exception as e:
            print(f"✗ 移除客户端失败: {e}")
            
    def _disconnect_client(self, client_id: str, reason: str = "unknown"):
        """
        断开客户端连接
        
        Args:
            client_id: 客户端ID
            reason: 断开原因
        """
        self.remove_client(client_id, reason)
        
    def _disconnect_all_clients(self):
        """断开所有客户端连接"""
        try:
            client_ids = list(self.clients.keys())
            for client_id in client_ids:
                self._disconnect_client(client_id, "server_shutdown")
        except Exception as e:
            print(f"✗ 断开所有客户端连接失败: {e}")
            
    def send_heartbeat(self, client_id: str = None):
        """
        发送心跳包
        
        Args:
            client_id: 客户端ID（None表示服务器发送给所有客户端）
        """
        try:
            heartbeat_data = {
                'timestamp': time.time()
            }
            
            if client_id:
                # 发送给特定客户端
                if self.plugin.protocol_handler:
                    self.plugin.protocol_handler.send_message('HEARTBEAT', heartbeat_data, client_id)
            else:
                # 发送给所有客户端
                if self.plugin.protocol_handler:
                    for cid in self.clients.keys():
                        self.plugin.protocol_handler.send_message('HEARTBEAT', heartbeat_data, cid)
                        
        except Exception as e:
            print(f"✗ 心跳包发送失败: {e}")
            
    def handle_heartbeat(self, client_id: str, data: Dict[str, Any]):
        """
        处理心跳包
        
        Args:
            client_id: 客户端ID
            data: 心跳数据
        """
        try:
            if client_id in self.clients:
                self.clients[client_id]['last_heartbeat'] = time.time()
                self.clients[client_id]['ping'] = time.time() - data.get('timestamp', time.time())
        except Exception as e:
            print(f"✗ 心跳包处理失败: {e}")
            
    def ban_ip(self, ip_address: str):
        """
        禁止IP地址
        
        Args:
            ip_address: IP地址
        """
        try:
            self.banned_ips.add(ip_address)
            print(f"✓ IP地址已被禁止: {ip_address}")
            
            # 断开该IP的所有连接
            clients_to_disconnect = [
                client_id for client_id, client_data in self.clients.items()
                if client_data.get('address', ('', 0))[0] == ip_address
            ]
            
            for client_id in clients_to_disconnect:
                self._disconnect_client(client_id, "banned")
                
        except Exception as e:
            print(f"✗ IP禁止失败: {e}")
            
    def unban_ip(self, ip_address: str):
        """
        解除IP地址禁止
        
        Args:
            ip_address: IP地址
        """
        try:
            if ip_address in self.banned_ips:
                self.banned_ips.remove(ip_address)
                print(f"✓ IP地址禁止已解除: {ip_address}")
        except Exception as e:
            print(f"✗ IP解除禁止失败: {e}")
            
    def get_clients(self) -> Dict[str, Any]:
        """
        获取所有客户端信息
        
        Returns:
            客户端信息字典
        """
        try:
            return {k: v.copy() for k, v in self.clients.items()}
        except Exception as e:
            print(f"✗ 客户端信息获取失败: {e}")
            return {}
            
    def get_client_count(self) -> int:
        """
        获取客户端数量
        
        Returns:
            客户端数量
        """
        return len(self.clients)
        
    def get_banned_ips(self) -> List[str]:
        """
        获取被禁止的IP地址列表
        
        Returns:
            被禁止的IP地址列表
        """
        return list(self.banned_ips)
        
    def is_client_connected(self, client_id: str) -> bool:
        """
        检查客户端是否连接
        
        Args:
            client_id: 客户端ID
            
        Returns:
            客户端是否连接
        """
        return client_id in self.clients
        
    def get_server_state(self) -> Dict[str, Any]:
        """
        获取服务器状态
        
        Returns:
            服务器状态字典
        """
        return self.server_state.copy()
        
    def get_client_state(self) -> Dict[str, Any]:
        """
        获取客户端状态
        
        Returns:
            客户端状态字典
        """
        return self.client_state.copy()
        
    def get_connection_stats(self) -> Dict[str, Any]:
        """
        获取连接统计信息
        
        Returns:
            连接统计字典
        """
        return self.connection_stats.copy()
        
    def reset_connection_stats(self):
        """重置连接统计信息"""
        try:
            self.connection_stats = {
                'connections_accepted': 0,
                'connections_rejected': 0,
                'connections_lost': 0,
                'connections_timed_out': 0,
                'reconnections': 0,
                'banned_connections': 0
            }
            print("✓ 连接统计信息已重置")
        except Exception as e:
            print(f"✗ 连接统计信息重置失败: {e}")
            
    def set_connection_config(self, config: Dict[str, Any]) -> bool:
        """
        设置连接配置
        
        Args:
            config: 连接配置字典
            
        Returns:
            是否设置成功
        """
        try:
            self.connection_config.update(config)
            print(f"✓ 连接配置已更新: {self.connection_config}")
            return True
        except Exception as e:
            print(f"✗ 连接配置设置失败: {e}")
            return False
            
    def get_connection_config(self) -> Dict[str, Any]:
        """
        获取连接配置
        
        Returns:
            连接配置字典
        """
        return self.connection_config.copy()
        
    def _trigger_connection_callback(self, callback_type: str, data: Dict[str, Any]):
        """
        触发连接回调
        
        Args:
            callback_type: 回调类型
            data: 回调数据
        """
        try:
            if callback_type in self.connection_callbacks:
                for callback in self.connection_callbacks[callback_type]:
                    try:
                        callback(data)
                    except Exception as e:
                        print(f"✗ 连接回调执行失败: {e}")
        except Exception as e:
            print(f"✗ 连接回调触发失败: {e}")
            
    def register_connection_callback(self, callback_type: str, callback: callable):
        """
        注册连接回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.connection_callbacks:
                self.connection_callbacks[callback_type].append(callback)
                print(f"✓ 连接回调已注册: {callback_type}")
            else:
                print(f"✗ 无效的回调类型: {callback_type}")
        except Exception as e:
            print(f"✗ 连接回调注册失败: {e}")
            
    def unregister_connection_callback(self, callback_type: str, callback: callable):
        """
        注销连接回调
        
        Args:
            callback_type: 回调类型
            callback: 回调函数
        """
        try:
            if callback_type in self.connection_callbacks:
                if callback in self.connection_callbacks[callback_type]:
                    self.connection_callbacks[callback_type].remove(callback)
                    print(f"✓ 连接回调已注销: {callback_type}")
        except Exception as e:
            print(f"✗ 连接回调注销失败: {e}")