package com.uas.eis.core.support;

import com.uas.eis.core.support.TokenProperties;
import com.uas.eis.dao.BaseDao;
import com.uas.eis.entity.ErrorMessage;
import com.uas.eis.exception.ApiSystemException;
import com.uas.eis.sdk.entity.ApiResult;
import com.uas.eis.utils.MD5Util;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.*;

@Service
public class ApiSignLoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private BaseDao baseDao;

    // 签名超时时长，默认时间为5分钟，ms
    private static final int SIGN_EXPIRED_TIME = 60 * 60 * 1000;
    private static final String ACCESS_KEY = "AccessKey";
    private static final String ACCESS_SECRET = "AccessSecret";
    private static final String TIMESTAMP_KEY = "Timestamp";
    private static final String SIGN_KEY = "Signature";
    private static final String RequestId = "RequestId";
    private static Map<String,String> tokenConfig = TokenProperties.getAllProperty();


    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Map<String, Object> result = new HashMap<String, Object>();
        String timestamp = request.getHeader(TIMESTAMP_KEY);
        String accessKey = request.getHeader(ACCESS_KEY);
        String requestId = request.getHeader(RequestId);

        //String accessSecret = tokenConfig.get(accessKey);
        //改用中心账套表取账户密码
        Object accessSecret_O = baseDao.getFieldDataByCondition("APIEMPLOYEE", "AE_SECRET", "AE_KEY='" + accessKey + "'");
        String accessSecret = accessSecret_O == null ? "" : accessSecret_O.toString();

        if (!StringUtils.isNumeric(timestamp)) {
            ApiResult apiResult = new ApiResult();
            apiResult.setCode(ErrorMessage.TIMESTAMP_ILLEGAL.getCode());
            apiResult.setMessage(ErrorMessage.TIMESTAMP_ILLEGAL.getMessage());
            apiResult.setRequestId(requestId);
            throw new ApiSystemException(apiResult);
        }

        // 检查KEY是否合理
        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(accessSecret)) {
            ApiResult apiResult = new ApiResult();
            apiResult.setCode(ErrorMessage.ACCESSKEY_ILLEGAL.getCode());
            apiResult.setMessage(ErrorMessage.ACCESSKEY_ILLEGAL.getMessage());
            apiResult.setRequestId(requestId);
            throw new ApiSystemException(apiResult);
        }

        Long ts = Long.valueOf(timestamp);
        // 禁止超时签名
        if (System.currentTimeMillis() - ts > SIGN_EXPIRED_TIME) {
            ApiResult apiResult = new ApiResult();
            apiResult.setCode(ErrorMessage.TIMEOUT_ILLEGAL.getCode());
            apiResult.setMessage(ErrorMessage.TIMEOUT_ILLEGAL.getMessage());
            apiResult.setRequestId(requestId);
            throw new ApiSystemException(apiResult);
        }

       /* String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
        String s = UUID.randomUUID().toString();
        System.out.println("uuid"+s);*/

        String regex = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
        if (!requestId.matches(regex)) {
            ApiResult apiResult = new ApiResult();
            apiResult.setCode(ErrorMessage.REQUESTID_ILLEGAL.getCode());
            apiResult.setMessage(ErrorMessage.REQUESTID_ILLEGAL.getMessage());
            apiResult.setRequestId(requestId);
            throw new ApiSystemException(apiResult);
        }

        if (!verificationSign(request, accessKey, accessSecret)) {
            ApiResult apiResult = new ApiResult();
            apiResult.setCode(ErrorMessage.SIGNATURE_ILLEGAL.getCode());
            apiResult.setMessage(ErrorMessage.SIGNATURE_ILLEGAL.getMessage());
            apiResult.setRequestId(requestId);
            throw new ApiSystemException(apiResult);
        }
        return true;
    }

    private boolean verificationSign(HttpServletRequest request, String accessKey, String accessSecret) throws UnsupportedEncodingException {
        Enumeration<?> pNames = request.getHeaderNames();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put(ACCESS_KEY,request.getHeader(ACCESS_KEY));
        params.put(RequestId,request.getHeader(RequestId));
        params.put(TIMESTAMP_KEY,request.getHeader(TIMESTAMP_KEY));
        String originSign = request.getHeader(SIGN_KEY);
        String sign = createSign(params, accessSecret);
        System.out.println(sign);

        return sign.equals(originSign);
    }

    private String createSign(Map<String, Object> params, String accessSecret) throws UnsupportedEncodingException {
        Set<String> keysSet = params.keySet();
        Object[] keys = keysSet.toArray();
        Arrays.sort(keys);
        StringBuilder temp = new StringBuilder();
        boolean first = true;
        for (Object key : keys) {
            if (first) {
                first = false;
            } else {
                temp.append("&");
            }
            temp.append(key).append("=");
            Object value = params.get(key);
            String valueString = "";
            if (null != value) {
                valueString = String.valueOf(value);
            }
            temp.append(valueString);
        }
        temp.append("&").append(ACCESS_SECRET).append("=").append(accessSecret);
        System.out.println(temp);
        System.out.println(MD5Util.encrypt32Up(temp.toString()));
       // System.out.println(MD5Util.getEncryption(temp.toString()));
        return MD5Util.encrypt32Up(temp.toString()).toUpperCase();
    }
}
