package cn.quantgroup.xyqb.session;

import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.model.session.SessionValue;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * Created by Miraculous on 2016/12/29.
 */
@Slf4j
public class XyqbSessionContextHolder {

    private static final ThreadLocal<SessionStruct> threadSession = new ThreadLocal<>();
    private static RedisTemplate<String, String> redisTemplate = null;

    public static void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
        XyqbSessionContextHolder.redisTemplate = redisTemplate;
    }

    public static SessionStruct getXSession() {
        SessionStruct sessionStruct;
        if (threadSession.get() != null) {
            sessionStruct = threadSession.get();
        } else {
            sessionStruct = getXSessionFromRedis();
            threadSession.set(sessionStruct);
        }
        return sessionStruct;
    }

    public static SessionStruct getXSessionFromRedis() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader(Constants.X_AUTH_TOKEN);
        log.info("getXSessionFromRedis token = 【{}】", token);
        return getXSessionFromRedis(token);
    }

    public static String getXSessionFromTenantRedis() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String tenantId = request.getHeader(Constants.X_AUTH_TENANT);
        log.info("getXSessionFromRedis tenantId = 【{}】", tenantId);
        return tenantId;
    }

    public static SessionStruct getXSessionFromRedis(String token) {
        if ( Objects.isNull(redisTemplate)) {
            return null;
        }
        String linkToken = Constants.Session.USER_SESSION_CACHE + token;
        String result = redisTemplate.opsForValue().get(linkToken);
        if (StringUtils.isEmpty(result)) {
            log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] Tokekn:{},linkTokekn:{}", token, linkToken);
            log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] session data 未找到：sid:{},sessionValue:{}", token, result);
            return null;
        }
        try {
            SessionValue values = JSON.parseObject(result, SessionValue.class);
            if (values == null) {
                log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] Tokekn:{},linkTokekn:{}", token, linkToken);
                log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] session data 序列化失败：sid:{},sessionValue:{}", token, result);
                return null;
            }
            SessionStruct sessionStruct = new SessionStruct();
            sessionStruct.setSid(token);
            sessionStruct.setValues(values);
            sessionStruct.setExpire(redisTemplate.getExpire(Constants.Session.USER_SESSION_CACHE + token));
            return sessionStruct;
        } catch (Exception e) {
            log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] Tokekn:{},linkTokekn:{}", token, linkToken);
            log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] 序列化SessionValue出错：sid:{},sessionValue:{}", token, result, e);
            return null;
        }
    }

    public static void releaseSession() {
        threadSession.remove();
    }
}
