package com.sonic.sdk.api.utils.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sonic.sdk.api.constants.WebHeaderConstant;
import com.sonic.sdk.api.exceptions.DecryptFailException;
import com.sonic.sdk.api.utils.AesEncodeUtil;
import com.sonic.sdk.api.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Slf4j
public class DecryptRequestBodyWrapper extends RequestBodyWrapper {

    /**
     * 混淆的 固定字符串
     */
    private static final String MIX = "Q8pD09kIeWXg8Ju";

    /**
     * token密钥的最大长度为 32 位
     */
    private static final Integer TOKEN_KEY_MAX_LEN = 32;

    /**
     * 内网访问认证标志密钥
     */
    private static final String IN_AH_CD_VALUE = "JUHYyte656VGT567uygu#2@89JH7g*yg@jxTQPXZMalje3";

    public DecryptRequestBodyWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //判断header头中是否携带了内网请求标志，如果有请求标志则不进行解密操作
        String innerAuthCode = request.getHeader("IN_AH_CD");
        if (StringUtils.isEmpty(innerAuthCode)) {
            //header头中没有找到的话从cookie中找
            innerAuthCode = getCookieValue(request, "IN_AH_CD");
        }
        String token = request.getHeader(WebHeaderConstant.AUTH_TOKEN);
        if (StringUtils.isNotEmpty(token) && !IN_AH_CD_VALUE.equals(innerAuthCode) && HttpMethod.POST.name().equals(request.getMethod())
                && (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType()) || MediaType.APPLICATION_JSON_UTF8_VALUE.equals(request.getContentType()))) {

            String oldBodyString = new String(super.body, "UTF-8");
            log.debug("开始解密请求参数:{}", oldBodyString);
            //截取token作为解密的密钥
            String tokenKey = token;
            if (token.length() > TOKEN_KEY_MAX_LEN) {
                tokenKey = token.substring(0, TOKEN_KEY_MAX_LEN);
            }
            String key = MD5Utils.stringToMD5(tokenKey + MIX).toUpperCase();
            log.debug("开始解密请求参数heder: token : {}, tokenKey: {}, key : {},mix:{}", token, tokenKey, key, MIX);

            JSONObject jsonObject = JSON.parseObject(oldBodyString);
            String encodeString = jsonObject.getString("key");

            String body;
            try {
                body = AesEncodeUtil.decrypt(encodeString, key);
            } catch (Exception e) {
                throw new DecryptFailException("Request parameter decryption failed");
            }
            log.debug("解密之后的请求参数:{}", body);
            if (StringUtils.isBlank(body)) {
                body = "{}";
            }
            this.body = body.getBytes();
        }
    }

    /**
     * 根据 Cookie 名称获取其值
     *
     * @param request HttpServletRequest 对象
     * @param name    Cookie 名称
     * @return Cookie 的值，如果不存在返回 null
     */
    public static 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;
    }

}
