package com.ajb.global.filter;

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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.httpclient.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;

import com.ajb.global.authorize.util.AudienceSetting;
import com.ajb.global.authorize.util.JwtTokenUtil;
import com.ajb.common.utils.string.CommonUtil;


/**
 * jwt过滤器
 * @author 
 * zuihuibi intercept all request from client, check whether token is there,verify the token is valid.
 */
public class HttpZuihuibiAuthorizeFilter implements Filter{
	@Autowired
	private JwtTokenUtil jwtTokenUtil;
	@Autowired
	private AudienceSetting audienceSetting;
	private static final String BY_PASS_ALL = "TEST";
	@Override
	public void destroy() {}

	/**
	 * 过滤器，对客户请求过滤，验证
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException{
	        HttpServletRequest httpRequest = (HttpServletRequest)request;
	        HttpServletResponse  httpResponse = (HttpServletResponse) response;
	        httpResponse.setHeader("Access-Control-Allow-Origin", "*");  
	        String requestUri = httpRequest.getRequestURI();
	        boolean isDoFilter = false;

	        //这里通过判断请求的方法，判断此次是否是预检请求，如果是，立即返回一个204状态吗，标示，允许跨域；预检后，正式请求，这个方法参数就是我们设置的post了
	        if ("OPTIONS".equals(httpRequest.getMethod())){
	        	//HttpStatus.SC_NO_CONTENT = 204
	        	httpResponse.setStatus(HttpStatus.SC_NO_CONTENT); 
	        	httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//当判定为预检请求后，设定允许请求的方法
	        	httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, Token, X-Authorization"); //当判定为预检请求后，设定允许请求的头部类型
	        	httpResponse.addHeader("Access-Control-Max-Age", "1"); 

	        	chain.doFilter(request, response);
                return;
	        }

	        String byPass = audienceSetting.bypass;
	        if(!CommonUtil.isNullOrBlank(byPass)){
	        	if(byPass.contains(BY_PASS_ALL)){//bypass配置为TEST时所有方法都放过
	        		isDoFilter = true;
	        	}else{
	        		if(byPass.contains(requestUri)){//完整路径匹配
	        			isDoFilter = true;
	        		}else{//按照“,”拆分后逐个模糊匹配
	        			String[] arr = byPass.split(",");
	        			for(String item : arr){
	        				if(item.startsWith("*") && item.endsWith("*")){//以*开头且以*结尾
	        					if(requestUri.contains(item.replace("*", ""))){
	        						isDoFilter = true;
	        						break;
	        					}
	        				}else if(item.startsWith("*")){//仅以*开头
	        					if(requestUri.endsWith(item.replace("*", ""))){
	        						isDoFilter = true;
	        						break;
	        					}
	        				}else if(item.endsWith("*")){//仅以*结尾
	        					if(requestUri.startsWith(item.replace("*", ""))){
	        						isDoFilter = true;
	        						break;
	        					}
	        				}
	        			}//for arr
	        		}//!byPass.contains(requestUri)
	        	}//not BY_PASS_ALL
	        }//byPass != null

	        if (isDoFilter){
                chain.doFilter(request, response);
                return;
	        }

	        //其他的URL请求，先获取head中的token，进行验证即可
	        int issuerLength = audienceSetting.issuer.length();
	        String token = httpRequest.getHeader(audienceSetting.header);
	        if(!CommonUtil.isNullOrBlank(token) && token.length() > issuerLength){
	            String headStr = token.substring(0, issuerLength).toLowerCase();
	            if (headStr.compareTo(audienceSetting.issuer) == 0){
	            	token = token.substring(issuerLength, token.length());
	            	//token格式合法并且没有失效
					if (jwtTokenUtil.validateToken(token) && !jwtTokenUtil.isTokenExpired(token)){
	                    chain.doFilter(request, response);
	                    return;
	                }
	            }
	        }

	        //验证失败，返回错误提示
	        httpResponse.setCharacterEncoding("UTF-8");
	        httpResponse.setContentType("application/json; charset=utf-8");
	        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
	        String responseJson = "{"
						        +"\n	\"success\": false,"
						        +"\n	\"errorCode\": \"T001\","
						        +"\n    \"message\": \"Invalid token!\""
						        +"\n}";
	        httpResponse.getWriter().write(responseJson);
	        return;  
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {}

}
