package xiaoqu.home.open.config;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;
import xiaoqu.home.open.constant.Constants;
import xiaoqu.home.open.constant.Errors;
import xiaoqu.home.open.service.RedisService4;
import xiaoqu.home.open.utils.IpUtils;
import xiaoqu.home.open.utils.ResultResponseBeanUtil;
import xiaoqu.home.open.utils.SignUtils;

@Component
@Slf4j(topic = "Controller")
public class SystemInterceptor implements HandlerInterceptor {

	private static final Pattern SHOULD_NOT_FILTER_URL_PATTERN;

	@Autowired
	private RedisService4 redisService4;

	static {
		List<String> urlList = new ArrayList<>();
		// 将不走拦截器的请求存放到Pattern
		urlList.add("/doc.html");
		urlList.add("/swagger-resources");
		urlList.add("/swagger-resources/configuration/ui");
		urlList.add("/*.js");
		urlList.add("/*.css");
		urlList.add("/*.ico");
		urlList.add("/*.gif");
		urlList.add("/v2/api-docs-ext");
		urlList.add("/login");
		urlList.add("/sms/sendCode");
		StringBuilder sb = new StringBuilder();
		for (String url : urlList) {
			sb.append(url);
			sb.append("|");
		}
		sb.setLength(sb.length() - 1);
		SHOULD_NOT_FILTER_URL_PATTERN = Pattern.compile(sb.toString());
	}

	/**
	 * 在请求处理之前进行调用（Controller方法调用之前）
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		String uuid = request.getHeader("uuid");
		String requestUrl = getBaseUrl(request);
		String ip = IpUtils.getIpAddr(request);
		String RefererIp = request.getHeader("Referer");
		log.info("客户IP=" + ip + "->RefererIp=" + RefererIp + "->requestUrl=" + requestUrl + "->UUID=" + uuid);
		if (requestUrl.contains("OPTIONS")) {
			return true;
		}
		response.setHeader("Cache-Control", "public");
		response.setCharacterEncoding("utf-8");
//		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("UTF-8");
		String servletPath = request.getServletPath();
		// 排除特定请求
		if (SHOULD_NOT_FILTER_URL_PATTERN.matcher(servletPath).find()) {
			return true;
		}
		if (uuid == null || "".equals(uuid)) {
			log.info("用户uuid为空请求地址=" + servletPath);
			PrintWriter out = response.getWriter();
			out.println(JSON.toJSON(ResultResponseBeanUtil.fail(Errors.USER_TOKEN_ERROR)));
			return false;
		} else {
			String mobile = redisService4.get(Constants.uuidToPcMobile + uuid);
			if (mobile == null) {
				log.error("用户uuid=" + uuid + "失效,请求地址=" + servletPath);
				PrintWriter out = response.getWriter();
				out.println(JSON.toJSON(ResultResponseBeanUtil.fail(Errors.USER_TOKEN_ERROR)));
				return false;
			}
			long TimeStampCompareChaLong = 10000;//默认上下10秒
			if (servletPath.contains("pload")) {//文件上传接口放宽时间
				TimeStampCompareChaLong = 60000;
			}
			// 验证万能的手机号 可以跳过验证
			if (redisService4.isMember("WanNengMobile", mobile)) {
				return true;
			}
			// 验证UUID
			String timeStamp = request.getHeader("timeStamp");
			String signature = request.getHeader("signature");
			if (timeStamp == null || signature == null) {
				log.error("时间戳或签名为空" + servletPath + " signature=" + signature + " timeStamp=" + timeStamp);
				PrintWriter out = response.getWriter();
				out.println(JSON.toJSON(ResultResponseBeanUtil.fail(Errors.PARAM_ERROR)));
				return false;
			}
			if (!SignUtils.compareTimeStamp(timeStamp, TimeStampCompareChaLong)) {
				log.error("时间戳失效:" + timeStamp + ",时间差=" + TimeStampCompareChaLong);
				PrintWriter out = response.getWriter();
				out.println(JSON.toJSON(ResultResponseBeanUtil.fail(Errors.TimeStamp_ERROR)));
				return false;
			}
			if (!SignUtils.getKey(uuid, timeStamp, mobile, signature)) {
				log.error("签名验证错误:" + uuid + " " + timeStamp + " " + mobile + " " + signature);
				PrintWriter out = response.getWriter();
				out.println(JSON.toJSON(ResultResponseBeanUtil.fail(Errors.Signature_ERROR)));
				return false;
			}
		}
		return true;
	}

	/**
	 * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}

	/**
	 * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		// TODO Auto-generated method stub

	}

	private String getBaseUrl(HttpServletRequest request) {
		String contextPath = request.getContextPath();
		String ctx = request.getScheme() + "://" + request.getServerName();
		int port = request.getLocalPort();
		if (port != 80) {
			ctx += ":" + port;
		}
		ctx += contextPath + request.getRequestURI() + "  Method=" + request.getMethod();

		return ctx;
	}
}
