package com.house365.web.interceptor;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.house365.commons.system.RemoteIpUtils;
import net.sf.json.JSONObject;

import org.apache.commons.codec.digest.DigestUtils;
import org.jasig.cas.client.util.AssertionHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.house365.rest.context.ServiceConstant;
import com.house365.rest.exception.ServiceException;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.web.util.UrlSortUtils;

/**
 * 对外核心业务URL参数拦截
 * <p/>
 * 核心业务抽奖模块加密处理逻辑
 *
 * @author jiangzhou
 * @version [版本号, 2015年10月25日]
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class UrlParamAuthInterceptor extends HandlerInterceptorAdapter {
    /**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger("InterfaceLog");
    /**
     * 获取私钥key
     */
    private static final String PRIVATE_KEY = "00BE62C08DE8A6366D467D6555C268CB";

    public static final String[] logApis = {"GetSignedCredits", "GetRegisterCredits", "RecordUserInvitation", "OrderSubmit", "CommentHouse", "HouseCommentReply", "HouseCommentPraise", "HouseCommentReplyPraise", "GetLotteryCredits", "SubmitSecKill", "saveAssess", "assessResult", "getAssess", "saveAssessScore", "deleteAssess", "addCreditByQuestion", "changeCredits", "bbsCredits", "questionMinusCredit"};

    public boolean preHandle(
        HttpServletRequest request, HttpServletResponse response, Object handler
    ) throws Exception {
        // 获取接口所有请求参数
        String url = request.getQueryString();

        if (request.getRequestURI().contains("/rest/interface")) {

            String serviceName = request.getParameter("serviceName") == null ? "" : request.getParameter("serviceName");
            String serviceCode = request.getParameter("serviceCode") == null ? "" : request.getParameter("serviceCode");
            if (!Strings.isNullOrEmpty(serviceName) && Lists.newArrayList(logApis).contains(serviceName)) {
                // 获取对端IP
                final String userIp = RemoteIpUtils.getIpAddr(request);
                LOGGER.info(
                    (request.getRequestURL() + "-" + request.getQueryString() + "-" + request.getRequestedSessionId() + "-" + userIp + "-" + JSONObject.fromObject(
                        request.getParameterMap()) + "-") + (request.getSession() != null ? request.getSession().getAttribute(
                        ServiceConstant.CITY_ID) : null));
            }

            //排除不需要的连接
            //载入需要验证的链接

            //            String urlNeedToVarify = MemoryPropertyPlaceholderConfigurer.getContextProperty("urlNeedToVarify");
            //            String[] urlNeedToVarifyArray = urlNeedToVarify.split(";");
            //            String[] serviceNameArr = request.getParameterValues("serviceName");
            //            if(serviceNameArr!=null && serviceNameArr.length>1){
            //                throw new ServiceException("非法来源请求");
            //            }
            //            for(String urlVar : urlNeedToVarifyArray){
            //                String serviceName = request.getParameter("serviceName");
            //                //如果是包含在内的请求
            //                if(urlVar.equals(serviceName)){
            String sign = request.getParameter("sign");

            List<String> validateService = Lists.newArrayList("RecordUserInvitation");
            if (!"Cm".equalsIgnoreCase(serviceCode)) {
                return true;
            }

            String version = request.getParameter("v") == null ? "" : request.getParameter("v");
            String api_key = request.getParameter("api_key") == null ? "" : request.getParameter("api_key");
            //android 7.0.0 not trans sign parameter ,ignore this version
            if ("7.0.0".equalsIgnoreCase(version) && "android".equalsIgnoreCase(api_key)) {
                return true;
            }

            if (!validateService.contains(serviceName)) {
                return true;
            }

            // 兼顾两种编码方式的hash值
            String encryptUrlDecoded = encrypt(url, true);
            String encryptUrl = encrypt(url, false);
            if (("127.0.0.1").equalsIgnoreCase(request.getRemoteAddr()) || ("localhost").equalsIgnoreCase(
                request.getRemoteAddr()) || (!Strings.isNullOrEmpty(sign) && (sign.equals(encryptUrl) || sign.equals(
                encryptUrlDecoded)))) {
                return true;
            } else {
                LOGGER.error(
                    "非法来源请求:" + (request.getRequestURL() + "-" + request.getQueryString() + "-" + request.getRequestedSessionId() + "-" + request.getRemoteAddr() + "-" + JSONObject.fromObject(
                        request.getParameterMap()) + "-") + (request.getSession() != null ? request.getSession().getAttribute(
                        ServiceConstant.CITY_ID) : null));
                throw new ServiceException("非法来源请求");
            }
            //                }
            //            }

        }
        return true;
    }

    /**
     * 功能描述: 接口参数排序加密算法<br>
     * 〈功能详细描述〉
     *
     * @param url
     * @return
     * @throws UnsupportedEncodingException
     * @author jiangzhou
     * @version [版本号, 2015年10月31日]
     * @since [产品/模块版本](可选)
     */
    public String encrypt(String url, boolean isUrlDecoded) throws UnsupportedEncodingException {
        if (isUrlDecoded) {
            url = URLDecoder.decode(url, "UTF-8");
        }
        // url参数排序
        String sortUrl = UrlSortUtils.sort(url);
        // 拼接秘钥
        sortUrl += "&key=" + PRIVATE_KEY;
        // MD5加密
        String encryptUrl = DigestUtils.md5Hex(sortUrl).toUpperCase();
        return encryptUrl;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        UrlParamAuthInterceptor ok = new UrlParamAuthInterceptor();
        //        String str = "serviceCode=Cm&serviceName=GetUploadUserPhotoCredits&userId=2447&userCityKey=nj&useridType=1&userPhoto=http://img12.house365.com/njbbsavatar/2014/12/16/2447_avatar_middle.jpg";
        String str = "api_key=iPhone&channl=app&city=nj&client=tf&inviteCode=509746&serviceCode=Cm&serviceName=RecordUserInvitation&userCityKey=nj&userId=1478287&useridType=1&v=6.1.7&version=6.1.7";
        String std = ok.encrypt(str, true);
        System.out.println(std);

    }
}
