package com.eactive.eai.agent.web;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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 com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;

public class FrontFilter implements Filter
{ 
    public static final String PROP_GROUP    = "FrontFilter";
    public static final String PROP_KEY1     = "SERVER_LIST";
    public static final String PROP_KEY2     = "CLIENT_LIST";
    
    public void init(FilterConfig config) throws ServletException{

    }

    public void destroy(){

    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
    throws IOException, ServletException{
        try {
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)res;
            PropManager manager = PropManager.getInstance();
            String serverList = manager.getProperty(PROP_GROUP,PROP_KEY1);
            String clientList = manager.getProperty(PROP_GROUP,PROP_KEY2);
            if(serverList==null) {
                Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
                logger.warn("[FrontFilter] Cannot configure the "+PROP_GROUP+"."+PROP_KEY1+" property.");
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"Cannot configure the "+PROP_GROUP+"."+PROP_KEY1+" property.");
                return;
            }
            
            if(clientList == null) clientList = "";
            
            String[] serverIpList = serverList.split(",");
            String[] clientIpList = clientList.split(",");
            
            Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

        	String remoteAddr = request.getRemoteAddr();
            if( isAllowedIP(serverIpList, remoteAddr) ) {
            	if(logger.isDebugEnabled()) {
                	logger.debug("FrontFilter] HTTP Access. server IP - " + remoteAddr);
                }
            }
            else if( isAllowedIP(clientIpList, remoteAddr) ) {
                if(logger.isDebugEnabled()) {
                	logger.debug("FrontFilter] HTTP Access. client IP - " + remoteAddr);
                }
            }
            else {
            	if(logger.isWarnEnabled()) {
	                logger.warn("FrontFilter] Invalid Access. - " + remoteAddr);
            	}
	            response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Access.");
                return;   
            }
            chain.doFilter(req,res);     
        } catch(Exception e) {
            Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
            logger.error("FrontFilter] Error - " + e.getMessage(), e);
            throw new ServletException(e.getMessage());
                   
        }
    }
    
    private boolean isAllowedIP(String[] ipList, String remoteIp) {
    	
    	if(ipList == null || ipList.length == 0) {
    		return false;
    	}
    	
    	for( String allow : ipList ) {
    		if (allow.indexOf('*') == -1) {
            	if (allow.equals(remoteIp)) {
            		return true;
            	}
            } else {
				String allowRegexp = allow.replaceAll("\\*", "[0-9]+").trim();
				Matcher matcher = Pattern.compile(allowRegexp, Pattern.CASE_INSENSITIVE).matcher(remoteIp);
				if (matcher.matches()) {
					return true;
				}
            }
    	}
    	return false;
    }
}