package com.xindazhou.message.config;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.store.RedissonStoreFactory;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

/**
 * SocketIO 配置类
 * 
 * 支持分布式部署：使用 Redis 作为存储后端，实现多服务器节点之间的消息同步
 * 支持 Engine.IO v3 协议（客户端使用）
 * 
 * 参考官方文档：https://www.socketio4j.org/server-api
 *
 * @author xindazhou
 */
@Slf4j
@org.springframework.context.annotation.Configuration
public class SocketIOConfig {

    @Value("${socketio.host:0.0.0.0}")
    private String host;

    @Value("${socketio.port:9090}")
    private Integer port;

    @Value("${socketio.context:/socket.io}")
    private String context;

    @Value("${socketio.max-frame-payload-length:1048576}")
    private int maxFramePayloadLength;

    @Value("${socketio.max-http-content-length:1048576}")
    private int maxHttpContentLength;

    @Value("${socketio.ping-timeout:60000}")
    private int pingTimeout;

    @Value("${socketio.ping-interval:25000}")
    private int pingInterval;

    @Value("${socketio.upgrade-timeout:10000}")
    private int upgradeTimeout;

    /**
     * SocketIO 服务器配置
     * 
     * 关键配置点（根据 socketio4j 官方文档）：
     * 1. context 必须设置为 "/socket.io"（默认值，但明确设置更安全）
     * 2. transports 默认支持 POLLING 和 WEBSOCKET（Engine.IO v3 需要）
     * 3. upgradeTimeout 用于 Polling → WebSocket 升级超时（默认 10 秒）
     * 4. CORS 必须启用，允许跨域请求
     * 
     * 如果项目中配置了 RedissonClient（通过 redisson-spring-boot-starter），
     * 则自动启用 Redis 存储，实现分布式消息同步
     */
    @Bean
    public SocketIOServer socketIOServer(RedissonClient redissonClient) {
        Configuration config = new Configuration();
        
        // ========== 网络和绑定配置 ==========
        config.setHostname(host);
        config.setPort(port);
        
        // 关键：必须设置 context 路径为 "/socket.io"
        // Engine.IO v3 客户端默认连接到此路径
        config.setContext(context);
        
        // ========== 传输协议配置（关键！）==========
        // 根据官方文档，必须明确设置传输方式：POLLING 和 WEBSOCKET
        // Engine.IO v3 客户端需要这两种传输方式：
        // 1. 先使用 HTTP 长轮询（POLLING）进行连接
        // 2. 然后升级到 WebSocket（WEBSOCKET）以获得更好的性能
        try {
            java.lang.reflect.Method setTransportsMethod = config.getClass()
                    .getMethod("setTransports", Transport[].class);
            setTransportsMethod.invoke(config, (Object) new Transport[]{Transport.POLLING, Transport.WEBSOCKET});
            log.info("已设置传输方式: POLLING, WEBSOCKET");
        } catch (Exception e) {
            // 如果方法不存在，使用默认值（通常默认已支持 POLLING 和 WEBSOCKET）
            log.debug("setTransports 方法不存在，使用默认传输方式");
        }
        
        // 关键：设置升级超时时间（Polling → WebSocket 升级）
        // 确保客户端能从 HTTP 长轮询成功升级到 WebSocket
        // 默认值是 10000ms（10秒），根据官方文档建议
        try {
            java.lang.reflect.Method upgradeTimeoutMethod = config.getClass()
                    .getMethod("setUpgradeTimeout", int.class);
            upgradeTimeoutMethod.invoke(config, upgradeTimeout);
            log.info("已设置 upgradeTimeout: {}ms", upgradeTimeout);
        } catch (Exception e) {
            // 如果方法不存在，使用默认值（通常是 10000ms）
            log.debug("setUpgradeTimeout 方法不存在，使用默认值 10000ms");
        }
        
        // ========== 负载和帧大小配置 ==========
        config.setMaxFramePayloadLength(maxFramePayloadLength);
        config.setMaxHttpContentLength(maxHttpContentLength);
        
        // ========== 心跳和超时配置 ==========
        config.setPingTimeout(pingTimeout);
        config.setPingInterval(pingInterval);
        
        // ========== CORS 配置（关键！）==========
        // 确保 CORS 已启用，允许跨域请求
        // Engine.IO v3 客户端可能需要跨域访问
        try {
            java.lang.reflect.Method enableCorsMethod = config.getClass()
                    .getMethod("setEnableCors", boolean.class);
            enableCorsMethod.invoke(config, true);
            log.info("已启用 CORS");
        } catch (Exception e) {
            log.debug("setEnableCors 方法不存在，可能默认已启用");
        }
        config.setOrigin("*");
        
        // ========== Redis 存储工厂（分布式支持）==========
        config.setStoreFactory(new RedissonStoreFactory(redissonClient));
        log.info("SocketIO Server 已启用 Redis 存储（分布式支持）");
        
        log.info("SocketIO Server 配置完成: host={}, port={}, context={}, pingInterval={}ms, pingTimeout={}ms, redis-enabled=true", 
                host, port, context, pingInterval, pingTimeout);
        
        SocketIOServer server = new SocketIOServer(config);
        return server;
    }

}

