package com.wecloud.im.ws.cache;

import com.wecloud.utils.GetIpUtils;
import com.wecloud.im.ws.model.redis.ClientChannelInfo;
import com.wecloud.im.ws.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author hewei123@163.com
 * @Description 用户与redis绑定
 * @createTime 2020年04月14日 16:21:00
 */
@Service
@Slf4j
public class UserStateCacheManager extends UserStateListener {

    /**
     * 维护client的多端数据:
     * 值为set集合,netty的channel的id
     */
    private static final String CLIENTS = "cis:";

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public void onLineEvent(Long clientId, Integer platform, String longChannelId) {
        log.info("ws用户上线保存redis连接ip: {}, uid: {}", GetIpUtils.getlanIp(), longChannelId);
        // 先删除旧的重复的platform
        Set<String> platformAndIps = redisUtils.getForSetMembers(getUserStateCacheKey(clientId));
        for(String platformAndIp : platformAndIps) {
            String[] split = platformAndIp.split(RedisUtils.SPLIT);
            String innerPlatform = split[0];
            if(innerPlatform.equals(String.valueOf(platform))) {
                redisUtils.removeForSet(getUserStateCacheKey(clientId), platformAndIp);
            }
        }

        redisUtils.addForSet(getUserStateCacheKey(clientId), platform + RedisUtils.SPLIT + GetIpUtils.getlanIp(), 10, TimeUnit.DAYS);
    }

    @Override
    public void offlineEvent(Long clientId, Integer platform, String longChannelId) {
        log.info("ws用户离线删除redis key,uid:" + longChannelId);
        redisUtils.removeForSet(getUserStateCacheKey(clientId), platform + RedisUtils.SPLIT + GetIpUtils.getlanIp());
    }

    /**
     * 根据clientId获取在线用户信息
     * @param clientId
     * @return
     */
    public List<ClientChannelInfo> findOnlineInfosByClientId(Long clientId) {

        // 获取所有 CLIENTS的 <platform>:<ip>
        Set<String> platformAndIps = redisUtils.getForSetMembers(getUserStateCacheKey(clientId));
        ArrayList<ClientChannelInfo> clientChannelInfos = new ArrayList<>();

        for(String platformAndIp : platformAndIps) {
            String[] split = platformAndIp.split(RedisUtils.SPLIT);
            ClientChannelInfo clientChannelInfo = new ClientChannelInfo();
            clientChannelInfo.setPlatform(Integer.valueOf(split[0]));
            clientChannelInfo.setLanIp(split[1]);
            clientChannelInfo.setClientId(String.valueOf(clientId));
            clientChannelInfos.add(clientChannelInfo);
        }

        return clientChannelInfos;
    }

    /**
     * 判断用户是否在线
     * @param clientId
     * @return true表示在线，false表示离线
     */
    public boolean isOnline(Long clientId) {
        Set<String> platformAndIs = redisUtils.getForSetMembers(getUserStateCacheKey(clientId));
        return platformAndIs.size() > 0;
    }

    private String getUserStateCacheKey(Long clientId) {
        return CLIENTS + clientId;
    }

}
