package cn.sikey.websocket.websocket;

import cn.sikey.websocket.config.CacheConnectionStateManager;
import cn.sikey.websocket.config.WebSocketConfig;
import cn.sikey.websocket.util.ConnectionConverterUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketSession;

import java.util.List;

/**
 * @Author: nelson
 * @Date: 2025/5/29
 * @Description: 连接管理
 */
@Slf4j
@Service
@RefreshScope
public class ConnectionManagerService {

    @Resource
    private CacheConnectionStateManager cacheConnectionStateManager;

    private WebSocketConfig webSocketConfig;

    @Autowired
    public void setWebSocketConfig(WebSocketConfig webSocketConfig) {
        this.webSocketConfig = webSocketConfig;
    }

    /**
     * 连接建立
     */
    public void connectionEstablished(WebSocketSession webSocketSession) throws Exception {
        log.info("Connection established");

        Connection connection = ConnectionConverterUtil.to(webSocketSession);
        cacheConnectionStateManager.online(connection, webSocketSession);
    }

    /**
     * 连接关闭
     */
    public void connectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) {
        log.info("Connection closed code: {}", closeStatus.getCode());

        Connection connection = ConnectionConverterUtil.to(webSocketSession);
        cacheConnectionStateManager.offline(connection);
    }

    /**
     * 移除死连接
     */
    public void removeDeadConnection() {
        List<Connection> connections = cacheConnectionStateManager.getConnections();
        log.debug("Remove dead connection. Current number of online connections: {}", connections.size());
        for (Connection connection : connections) {
            if (connection.isDead(webSocketConfig.getHeartbeatTimeout().plus(webSocketConfig.getCheckTimeout()))) {
                log.info("Remove dead connection. Connection: {}", connection);
                cacheConnectionStateManager.offline(connection);
            }
        }
    }
}
