package ink.wgink.module.instantmessage.websocket.manager;

import ink.wgink.exceptions.websocket.SessionException;
import ink.wgink.interfaces.manager.IWebSocketUserSessionManager;
import ink.wgink.pojo.session.WebSocketSession;
import io.netty.channel.Channel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @ClassName: DefaultWebSocketChannelManager
 * @Description: 默认websocket管理器
 * @Author: wanggeng
 * @Date: 2021/11/30 9:46 上午
 * @Version: 1.0
 */
@Service
public class DefaultWebSocketUserSessionManager implements IWebSocketUserSessionManager {

    private ConcurrentMap<String, List<WebSocketSession>> webSocketUserMap = new ConcurrentHashMap<>();

    @Override
    public void init(String userId, String sessionId, String clientName) {
        WebSocketSession onlineUser = new WebSocketSession();
        onlineUser.setUserId(userId);
        onlineUser.setClientName(clientName);
        onlineUser.setSessionId(sessionId);
        onlineUser.setUpdateTime(System.currentTimeMillis());
        List<WebSocketSession> webSocketSessions = listOnlineUser(userId);
        webSocketSessions.add(onlineUser);
        webSocketUserMap.put(userId, webSocketSessions);
    }

    @Override
    public WebSocketSession addChannel(String sessionId, String userId, Channel channel) throws SessionException {
        WebSocketSession onlineUser = getOnlineUserBySessionId(sessionId);
        if (onlineUser == null) {
            throw new SessionException("无效会话，请登录");
        }
        if (!StringUtils.equals(userId, onlineUser.getUserId())) {
            throw new SessionException("from错误");
        }
        // 更新会话通道
        onlineUser.setChannel(channel);
        onlineUser.setChannelId(channel.id().asLongText());
        return onlineUser;
    }

    @Override
    public void removeChannel(Channel channel) {
        // 获取session
        for (Map.Entry<String, List<WebSocketSession>> kv : webSocketUserMap.entrySet()) {
            List<WebSocketSession> webSocketSessions = kv.getValue();
            for (int i = 0; i < webSocketSessions.size(); i++) {
                WebSocketSession webSocketSession = webSocketSessions.get(i);
                if (StringUtils.equals(webSocketSession.getChannelId(), channel.id().asLongText())) {
                    webSocketSessions.remove(i);
                    return;
                }
            }
        }
    }

    @Override
    public List<WebSocketSession> listOnlineUser(String userId) {
        if (StringUtils.isBlank(userId)) {
            return new ArrayList<>();
        }
        List<WebSocketSession> webSocketSessions = webSocketUserMap.get(userId);
        if (webSocketSessions == null) {
            return new ArrayList<>();
        }
        return webSocketSessions;
    }

    @Override
    public List<WebSocketSession> listOnlineUser(String userId, String clientName) {
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(clientName)) {
            return new ArrayList<>();
        }
        List<WebSocketSession> webSocketSessions = listOnlineUser(userId);
        if (webSocketSessions.isEmpty()) {
            return webSocketSessions;
        }
        List<WebSocketSession> clientNameWebSocketSessions = new ArrayList<>();
        for (WebSocketSession webSocketSession : webSocketSessions) {
            if (StringUtils.equals(clientName, webSocketSession.getClientName())) {
                clientNameWebSocketSessions.add(webSocketSession);
            }
        }
        return clientNameWebSocketSessions;
    }

    @Override
    public List<WebSocketSession> listOnlineUser(List<String> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return new ArrayList<>();
        }
        List<WebSocketSession> webSocketSessions = new ArrayList<>();
        for (String userId : userIds) {
            List<WebSocketSession> users = webSocketUserMap.get(userId);
            if (users != null) {
                webSocketSessions.addAll(users);
            }
        }
        return webSocketSessions;
    }

    @Override
    public List<WebSocketSession> listOnlineUser(List<String> userIds, String clientName) {
        if (userIds == null || userIds.isEmpty() || StringUtils.isBlank(clientName)) {
            return new ArrayList<>();
        }
        List<WebSocketSession> webSocketSessions = new ArrayList<>();
        for (String userId : userIds) {
            List<WebSocketSession> users = webSocketUserMap.get(userId);
            if (users == null) {
                continue;
            }
            for (WebSocketSession user : users) {
                if (StringUtils.equals(clientName, user.getClientName())) {
                    webSocketSessions.add(user);
                }
            }
        }
        return webSocketSessions;
    }

    @Override
    public WebSocketSession getOnlineUserBySessionId(String sessionId) {
        for (Map.Entry<String, List<WebSocketSession>> kv : webSocketUserMap.entrySet()) {
            for (WebSocketSession webSocketSession : kv.getValue()) {
                if (StringUtils.equals(sessionId, webSocketSession.getSessionId())) {
                    return webSocketSession;
                }
            }
        }
        return null;
    }

    @Override
    public WebSocketSession getOnlineUserByChannelId(String channelId) {
        for (Map.Entry<String, List<WebSocketSession>> kv : webSocketUserMap.entrySet()) {
            for (WebSocketSession webSocketSession : kv.getValue()) {
                if (StringUtils.equals(channelId, webSocketSession.getChannelId())) {
                    return webSocketSession;
                }
            }
        }
        return null;
    }


}
