package com.yd.util.auth.filter;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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 org.springframework.http.HttpStatus;

import com.yd.dal.entity.customer.AclCustomerSystemLog;
import com.yd.dal.service.customer.AclCustomerLogDALService;
import com.yd.util.CommonUtil;
import com.yd.util.auth.setting.AudienceSetting;
import com.yd.util.auth.setting.JwtTokenUtil;

/**
 * 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;
    @Autowired
    private AclCustomerLogDALService aclCustomerLogDALService;

	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", "*");
	        httpResponse.setHeader("x-frame-options","x-frame-options");
	        String requestUri = httpRequest.getRequestURI();
	        boolean isDoFilter = false;
	    	
	        //这里通过判断请求的方法，判断此次是否是预检请求，如果是，立即返回一个204状态吗，标示，允许跨域；预检后，正式请求，这个方法参数就是我们设置的post了
	        if ("OPTIONS".equals(httpRequest.getMethod())){
	        	//HttpStatus.SC_NO_CONTENT = 204
	        	httpResponse.setStatus(HttpStatus.NO_CONTENT.value()); 
	        	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

	        
	        //其他的URL请求，先获取head中的token，进行验证即可
	        boolean boole = false;
	        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)){
						boole = true;
						final String customerId = jwtTokenUtil.getCustomerIdToken(token);
						final String tokenFinal = token;
				        if(!CommonUtil.isNullOrBlank(customerId)){
				        	ExecutorService executor = Executors.newSingleThreadExecutor();
							executor.execute(new Runnable() {
								@Override
								public void run(){
						        	AclCustomerSystemLog aclCustomerSystemLog = new AclCustomerSystemLog();
						        	aclCustomerSystemLog.setCustomerId(Long.valueOf(customerId));
					        		aclCustomerSystemLog.setToken(tokenFinal);
						        	aclCustomerSystemLog.setExpiredMinute(5);
						        	List<AclCustomerSystemLog> aclCustomerSystemLogList = aclCustomerLogDALService.findCustomerSystemLog(aclCustomerSystemLog);
						        	if(aclCustomerSystemLogList != null && aclCustomerSystemLogList.size() > 0){
						        		aclCustomerLogDALService.updateEndTimeByPrimaryKey(aclCustomerSystemLogList.get(0).getId());
						        	}else{
						        		aclCustomerSystemLog.setIsActive(1);
						        		aclCustomerSystemLog.setFromSystem("1");
						        		aclCustomerLogDALService.saveAclCustomerSystemLog(aclCustomerSystemLog);
						        	}
								}
							});
				        }
	                }
	            }
	        }
	        
	        if (isDoFilter){
                chain.doFilter(request, response);
                return;
	        }

	        /*
	        if (!isIpValid("ProdCheckIP") || !isIpValid("StageCheckIP")) {
				if("autogeneral".equals(token)){
					chain.doFilter(request, response);
                    return;
				}
			}*/
	        if(boole && !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\": \"请联系管理员，开通API访问账号!\""
						        +"\n}";
	        httpResponse.getWriter().write(responseJson);
	        return;  
	}

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

/*	@SuppressWarnings("unused")
	private boolean isIpValid(String configType){
		boolean ipValid = false;
		String currentIP = CommonUtil.currentIP();
		String validIPS = systemConfigService.getSingleConfigValue(configType);
		if(!CommonUtil.isNullOrBlank(currentIP) && !CommonUtil.isNullOrBlank(validIPS)){
			String[] arr = validIPS.split("\\|");
			for(String item : arr){
				if(currentIP.contains(item)){
					ipValid = true;
					break;
				}
			}
		}
		return ipValid;
	}*/
}
