package com.sonic.common.auth;

import com.alibaba.fastjson.JSON;
import com.sonic.common.auth.domains.Session;
import com.sonic.common.utils.IpAddressUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;


/**
 * 解析请求头  得到 session 对象
 * 也可以模拟 x-id 构造一个对象
 */
@Slf4j
public class GateWaySessionInterceptor implements HandlerInterceptor {

    public static final String REQUEST_ATTR_SESSION = "_session_";
    private static final String DEBUG_USER_ID = "x-id";
    private static final String GATE_WAY_SESSION_JSON = "gateway-session-json";

    /**
     * 只有移动端在传
     */
    private static final String PLATFORM = "platform";
    private static final String VERSION_NUM = "versionNum";
    private static final String USER_AGENT = "User-Agent";
    /**通过header头传过来的设备号*/
    private static final String DEVICE_ID = "AUTH_DID";
    /**通过cookie传过来的设备号*/
    private static final String COOKIE_DEVICE_ID_KEY = "COOKIE_DID";

    @Value("${session.interceptor.skip:false}")
    private String skipSessionInterceptor;

    @Value("${spring.profiles.active}")
    private String runMode;

    /**
     * 环境变量列表
     */
    private static final List<String> devList = new ArrayList<>();
    {
        devList.add("local");
        devList.add("dev");
        devList.add("test");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        if (!(handler instanceof HandlerMethod)) {
            log.info("GateWaySessionInterceptor no instanceof");
            return true;
        }
        String json = request.getHeader(GATE_WAY_SESSION_JSON);
        log.info("GateWaySessionInterceptor json:{}", json);
        String deviceId = getValue(request, DEVICE_ID, COOKIE_DEVICE_ID_KEY);
        String ip = IpAddressUtils.getIpAddress(request);;
        String versionNum = getValue(request, VERSION_NUM, VERSION_NUM);
        String platform = getValue(request, PLATFORM, PLATFORM);
        //当使用mock的用户ID时只能在指定的环境生效（local/dev/test）
        if ("true".equals(skipSessionInterceptor) && devList.contains(runMode) && StringUtils.isBlank(json)) {
            String userId = request.getHeader(DEBUG_USER_ID);
            Session session = new Session();
            session.setUserId(StringUtils.isEmpty(userId) ? null : Long.valueOf(userId));
            //设置设备信息
            session.setDeviceCode(deviceId);
            session.setIp(ip);
            session.setVersionNum(StringUtils.isEmpty(versionNum) ? 0 : Integer.valueOf(versionNum));
            session.setEndpoint(platform);
            //浏览器基础信息
            session.setUserAgent(request.getHeader(USER_AGENT));
            request.setAttribute(REQUEST_ATTR_SESSION, session);
            return true;
        }
        Session session = new Session();
        if (StringUtils.isNotBlank(json)) {
            session = JSON.parseObject(json, Session.class);
        }
        //设置设备信息
        session.setDeviceCode(deviceId);
        session.setIp(ip);
        session.setVersionNum(StringUtils.isEmpty(versionNum) ? 0 : Integer.valueOf(versionNum));
        session.setEndpoint(platform);
        //设置语言、浏览器基础信息
        session.setUserAgent(request.getHeader(USER_AGENT));
        log.info("GateWaySessionInterceptor session:{}", session);
        request.setAttribute(REQUEST_ATTR_SESSION, session);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

    /**
     * 首先从header头中获取值，没有获取到再从cooke获取
     * @param request
     * @param key1
     * @param key2
     * @return
     */
    private String getValue(HttpServletRequest request, String key1, String key2) {
        String value = request.getHeader(key1);
        if(StringUtils.isEmpty(value)) {
            value = getCookieValue(request, key2);
        }
        return value;
    }

    /**
     * 根据 Cookie 名称获取其值
     *
     * @param request HttpServletRequest 对象
     * @param name    Cookie 名称
     * @return Cookie 的值，如果不存在返回 null
     */
    private String getCookieValue(HttpServletRequest request, String name) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    return cookie.getValue();
                }
            }
        }
        return null;
    }

}
