package ink.wgink.app;

import com.alibaba.fastjson.JSONObject;
import ink.wgink.exceptions.TokenException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.interfaces.manager.IAppManager;
import ink.wgink.interfaces.manager.IAppTokenService;
import ink.wgink.pojo.app.AppToken;
import ink.wgink.pojo.app.AppTokenUser;
import ink.wgink.util.AesUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: AppTokenManager
 * @Description: AppToken管理
 * @Author: WangGeng
 * @Date: 2019-08-02 11:08
 * @Version: 1.0
 **/
public class AppTokenManager implements IAppManager {

    private static final Logger LOG = LoggerFactory.getLogger(AppTokenManager.class);
    private static AppTokenManager appTokenManager = AppTokenManagerBuilder.appTokenManager;

    private IAppTokenService appTokenService;

    private AppTokenManager() {
    }

    public static AppTokenManager getInstance() {
        return appTokenManager;
    }

    /**
     * 获取token
     *
     * @param token
     * @return
     */
    @Override
    public AppToken getToken(String token) {
        return appTokenService.getToken(token);
    }

    /**
     * 添加token
     *
     * @param token
     * @param appTokenTypeEnum
     * @param appTokenUser
     */
    public synchronized void addToken(String token, AppToken.AppTokenTypeEnum appTokenTypeEnum, AppTokenUser appTokenUser) {
        appTokenService.addToken(token, appTokenTypeEnum, appTokenUser);
    }

    @Override
    public AppTokenUser parseToAppTokenUser(String token) throws TokenException {
        String userInfo = null;
        try {
            userInfo = AesUtil.aesCommonDecoder(ISystemConstant.APP_TOKEN_AES_KEY, new String(Base64.decodeBase64(token), "UTF-8"));
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            throw new TokenException("Token解码异常");
        }
        JSONObject userInfoObj = JSONObject.parseObject(userInfo);
        if (userInfoObj == null) {
            throw new TokenException("Token非法");
        }
        String appTokenSign = userInfoObj.getString(ISystemConstant.APP_TOKEN_SIGN);
        if (StringUtils.isBlank(appTokenSign)) {
            LOG.debug("Token标识为空");
            throw new TokenException("Token非法");
        }
        if (!StringUtils.startsWith(appTokenSign, ISystemConstant.APP_TOKEN_VERIFY)) {
            LOG.debug("Token标识开头错误");
            throw new TokenException("Token非法");
        }
        String[] appTokenSignArray = appTokenSign.split("_");
        if (appTokenSignArray.length != 3) {
            LOG.debug("Token标识格式长度异常，应为3，这里为：{}", appTokenSignArray.length);
            throw new TokenException("Token非法");
        }
        try {
            new Date(Long.parseLong(appTokenSignArray[2]));
        } catch (NumberFormatException e) {
            e.printStackTrace();
            LOG.debug("Token时间戳异常");
            throw new TokenException("Token非法");
        }
        return JSONObject.toJavaObject(userInfoObj, AppTokenUser.class);
    }

    /**
     * 当前用户列表
     *
     * @return
     */
    @Override
    public List<AppTokenUser> listCurrentUsers() {
        return appTokenService.listCurrentUsers();

    }

    /**
     * 清空超时Token
     */
    public synchronized void clearTimeoutToken() {
        appTokenService.clearTimeoutToken();
    }

    @Override
    public void setAppTokenService(IAppTokenService appTokenService) {
        this.appTokenService = appTokenService;
    }

    private static class AppTokenManagerBuilder {
        public static final AppTokenManager appTokenManager = new AppTokenManager();
    }

}
