package ink.wgink.module.wechat.manager;

import ink.wgink.exceptions.SearchException;
import ink.wgink.module.wechat.pojo.bos.miniapp.MiniappUserInfoBO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: WechatMiniAppManager
 * @Description: 微信小程序管理
 * @Author: WangGeng
 * @Date: 2020/5/9 18:05
 * @Version: 1.0
 **/
public class MiniappManager {

    private static final Logger LOG = LoggerFactory.getLogger(MiniappManager.class);
    private static MiniappManager miniAppManager = WechatMiniAppManagerBuilder.MINI_APP_MANAGER;
    // 超时分钟
    private final int TIME_OUT_SECOND = 120 * 60;

    private MiniappManager() {
    }

    private Map<String, MiniappUserInfoBO> users = new ConcurrentHashMap<>();

    public static MiniappManager getInstance() {
        return miniAppManager;
    }

    /**
     * 添加用户
     *
     * @param userId
     * @param miniappUserInfoBO
     */
    public void addUser(String userId, MiniappUserInfoBO miniappUserInfoBO) {
        miniappUserInfoBO.setUpdateTime(System.currentTimeMillis());
        users.put(userId, miniappUserInfoBO);
    }

    /**
     * 刷新用户更新时间
     *
     * @param userId
     */
    public void refreshUserUpdateTime(String userId) {
        MiniappUserInfoBO miniappUserInfoBO = get(userId);
        if (miniappUserInfoBO == null) {
            throw new SearchException("会话不存在，请重新打开小程序");
        }
        addUser(userId, miniappUserInfoBO);
    }

    /**
     * 获取小程序应用
     *
     * @param userId
     * @return
     */
    public MiniappUserInfoBO get(String userId) {
        return users.get(userId);
    }

    /**
     * 删除小程序应用
     *
     * @param token
     * @return
     */
    public MiniappUserInfoBO remove(String token) {
        return users.remove(token);
    }

    /**
     * 删除超时用户
     */
    public void removeTimeout() {
        LOG.debug("delete timeout wechat mini app user start");
        long startTime = System.currentTimeMillis();
        List<String> tokenList = new ArrayList<>();
        for (Map.Entry<String, MiniappUserInfoBO> kv : users.entrySet()) {
            // 超时
            if ((startTime - kv.getValue().getUpdateTime()) / 1000 > TIME_OUT_SECOND) {
                tokenList.add(kv.getKey());
            }
        }
        for (String token : tokenList) {
            users.remove(token);
        }
        long endTime = System.currentTimeMillis();
        LOG.debug("delete timeout wechat mini app user end, delete count: {}, useTime: {}ms", tokenList.size(), endTime - startTime);
    }

    private static class WechatMiniAppManagerBuilder {
        public static final MiniappManager MINI_APP_MANAGER = new MiniappManager();
    }
}
