package com.cm.token;

import com.cm.security.utils.AesUtil;
import org.apache.commons.codec.binary.Base64;

/**
 * @author Administrator
 * @version 1.0
 * @className TokenDecoder
 * @description TODO
 * @date 2018/12/7 14:12
 **/
public class TokenDecoder implements IToken {

    private static final String DECODE_RULE = "CMXX";
    private static final String SPLIT_CONTENT = "_C450292408M_";
    private String token;
    private String[] tokenParams;
    private long tokenCreateTime;
    private String key;
    private String value;
    private String content;
    private int tokenType;
    private boolean isDecode;
    private TokenDecoder(String token) {
        this.token = token;
    }

    /**
     * 解密Token
     *
     * @param token
     * @return
     */
    public static TokenDecoder getDecoder(String token) throws Exception {
        if (null == token) {
            throw new Exception("token can't contain null value");
        }
        return new TokenDecoder(token);
    }

    /**
     * 解码
     *
     * @return
     * @throws Exception
     */
    public TokenDecoder decode() throws Exception {
        token = AesUtil.aesDecoder(DECODE_RULE, new String(Base64.decodeBase64(token), CHARSET_NAME_UTF_8));
        this.tokenParams = token.split(SPLIT_CONTENT);
        String tokenPrefix = this.tokenParams[0];
        String tokenSuffix = this.tokenParams[tokenParams.length - 1];
        // token 前缀
        if (TOKEN_PREFIX_DEFAULT.equals(tokenPrefix)) {
            this.tokenType = TOKEN_TYPE_DEFAULT;
            this.tokenCreateTime = Long.valueOf(tokenParams[1]);
        } else if (TOKEN_PREFIX_CONTENT.equals(tokenPrefix)) {
            this.tokenType = TOKEN_TYPE_CONTENT;
            this.tokenCreateTime = Long.valueOf(tokenParams[2]);
            this.content = tokenParams[1];
        } else if (TOKEN_PREFIX_KEY_AND_VALUE.equals(tokenPrefix)) {
            this.tokenType = TOKEN_TYPE_KEY_AND_VALUE;
            this.tokenCreateTime = Long.valueOf(tokenParams[3]);
            this.key = tokenParams[1];
            this.value = tokenParams[2];
        } else {
            throw new Exception("token error");
        }
        // token 后缀
        if (!TOKEN_SUFFIX.equals(tokenSuffix)) {
            throw new Exception("token error");
        }
        this.isDecode = true;
        return this;
    }

    /**
     * token是否有效
     *
     * @return
     */
    public boolean isTokenEffective() {
        if (!this.isDecode) {
            System.out.println("Please execute method ‘decode’ first");
            return false;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - this.tokenCreateTime > TOKEN_EFFECTIVE_TIME) {
            return false;
        }
        return true;
    }

    /**
     * token是否有效
     *
     * @param timeout 超时时间
     * @return
     */
    public boolean isTokenEffective(long timeout) {
        if (!this.isDecode) {
            System.out.println("Please execute method ‘decode’ first");
            return false;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - this.tokenCreateTime > timeout) {
            return false;
        }
        return true;
    }

    /**
     * 获取token内容
     *
     * @return
     */
    public String[] getTokenContents() {
        if (!this.isDecode) {
            System.out.println("Please execute method ‘decode’ first");
            return null;
        }
        String[] contents = null;
        switch (this.tokenType) {
            case TOKEN_TYPE_CONTENT:
                contents = new String[]{this.content};
                break;
            case TOKEN_TYPE_KEY_AND_VALUE:
                contents = new String[]{this.key, this.value};
                break;
            default:
                contents = new String[0];
                break;
        }
        return contents;
    }

}
