package com.iamberry.wechat.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.iamberry.wechat.core.entity.WechatUtils;
import com.iamberry.wechat.core.entity.member.Member;
import com.iamberry.wechat.tools.NameUtils;
/**
 * @company	深圳爱贝源科技有限公司
 * @website www.iamberry.com
 * @author 	献
 * @tel		18271840547
 * @date	2016年11月3日
 * @explain	完成和微信自动登录的过程，如果登录，那么通过，否则自动登录，完成Oauth过程
 */
@WebFilter(value = { "/wechat/*","/pay/goOrderInfo" })
public class WechatFilter implements Filter {

	private static Logger logger = LoggerFactory.getLogger(WechatFilter.class);

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// 权限拦截类
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		//获取Spring Ioc 容器
		WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
		WechatUtils wechatUtils = context.getBean(WechatUtils.class);
		try {
			Member member = wechatUtils.getUserBySession(req);
			// 用户登录，通过此次过滤
			if (member != null) {
				chain.doFilter(req, resp);
				return;
			}
			
			// 请求数据URI，并去掉"/" + 项目名称
			String query = req.getQueryString();
			String urlstr = req.getRequestURI().toString();
			String redirectUrl = urlstr.replace(req.getContextPath(), "");

			// 如果没有登录，并且来自于微信，请求的链接并且为/wechat/qrcode/xxxx,那么放过，保证可以保持机器信息
			String ua = req.getHeader("user-agent").toLowerCase();
			if( ua.indexOf("micromessenger") < 0 && urlstr.indexOf("wechat/qrcode") > 0) {
				chain.doFilter(req, resp);
				return;
			}

			// 到此就准备开始授权的流程，并且保证转发后再次定位到当前请求页面
			if (query != null) redirectUrl = redirectUrl + "?" + query;
			req.getSession().setAttribute(NameUtils.redirectUrl, redirectUrl);
			String url = WechatUtils.getOpenIdFunction();
			
			// 判断请求,如果来自于Ajax，那么不能直接转发，否则JS前端报错，如果来自Ajax，那么报错请求页面的Referer，此为转发请求回调成功后跳转地址
			String requestedWith = req.getHeader("x-requested-with");
			String accept = req.getHeader("accept");
			if ((StringUtils.isNotEmpty(requestedWith) && requestedWith.indexOf("XMLHttpRequest") != -1) 
					|| (StringUtils.isNotEmpty(accept) && accept.indexOf("json") != -1)) {
				// 如果当前用户没有登录，并且浏览器期望的是返回JSON格式的数据，那么进行拼装，并且直接write
				String redirectURL = req.getHeader("Referer");
				if (redirectURL != null) {
					req.getSession().setAttribute(NameUtils.redirectUrl, redirectURL);
				}
				resp.getWriter().write("{\"isRedirect\":true, \"redirectURL\":\"" + url + "\"}");
				return;
			}
			req.getSession().setAttribute(NameUtils.redirectUrl, redirectUrl);
			// 可以直接跳转
			resp.sendRedirect(url);
		} catch (Exception e) {
			// 如果失败，记录日志，然后转发首页
			logger.error(e.getMessage() + "," + e.getLocalizedMessage());
			resp.sendRedirect(WechatUtils.getOpenIdFunction());
		}
	}

	public void setRequestDispatcherInfo(HttpServletRequest req, HttpServletResponse resp, String url)
			throws ServletException, IOException {
		resp.sendRedirect(url);
	}
	public void init(FilterConfig fConfig) throws ServletException {}
	public void destroy() {}
}
