package com.eactive.eai.adapter.http.client.impl.filter;

import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;

import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.util.Logger;

public class AllHeaderFilter implements HttpClientAdapterFilter, HttpAdapterServiceKey {
	protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);
	
	public static final String PROPERTIES_GROUP_NAME = "HttpHeaderFilter";
	public static final String HEADER_KEY_NAMES = "AllHeaderFilter.blackList";


	String[] HttpHeaderRelayBlackList = {
			"Content-Length",
			"Transfer-Encoding",
			"Host",
			"Authorization",
			"Accept",
			"Host",
			"Cookie",
			"Connection",
			"Keep-Alive",
			"Proxy-Authenticate",
			"Proxy-Authorization",
			"TE",
			"Trailer",
			"Transfer-Encoding",
			"Upgrade",
			"Content-Type",
			"Content-Encoding",
			"Content-Language",
			"Content-Location",
			"Content-MD5",
			"Expect",
	};
	
	@Override
	public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
			throws Exception {

		logger.debug("doPreFilter Processing Start.");

		Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
		if (filterHeaders == null) {
			filterHeaders = new Properties();
			tempProp.put("FILTERHEADER", filterHeaders);
		}
		
		Map<String, String> inboundHeaderMap = getInboundHeaderProp(tempProp);
		
		String propValue = PropManager.getInstance().getProperty(PROPERTIES_GROUP_NAME, HEADER_KEY_NAMES, "").trim();
		
		String[] userSettingBlackList = propValue.split(",");
		
		if( userSettingBlackList.length > 0 ) {
			HttpHeaderRelayBlackList = Stream
			        .concat(Arrays.stream(HttpHeaderRelayBlackList), Arrays.stream(userSettingBlackList))
			        .toArray(String[]::new);
		}
		
		
		for(String keyName : inboundHeaderMap.keySet() ) {
			
			if( StringUtils.equalsAnyIgnoreCase( keyName, HttpHeaderRelayBlackList ) ) {
				logger.debug("Skip Processing Key ["+keyName+"], value ["+inboundHeaderMap.get(keyName)+"] in HttpHeaderRelayBlackList");
				continue;
			}
			
			filterHeaders.put(keyName, inboundHeaderMap.get(keyName));
			logger.debug("Processing Key ["+keyName+"], value ["+inboundHeaderMap.get(keyName)+"]");
		}
		
		logger.debug("doPreFilter Processing End.");
		
		return message;
	}
	
	public Map<String, String> getInboundHeaderProp(Properties prop) {
		Properties header = new Properties();
		Map<String, String> inboundHeaderMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
		try {
			Object headerObj = prop.get(HttpAdapterServiceKey.INBOUND_HEADER);
			if (headerObj instanceof Properties) {    //tomcat
				header = (Properties) headerObj;
				for (String name : header.stringPropertyNames()) {
					inboundHeaderMap.put(name, header.getProperty(name));
				}
			} else if (headerObj instanceof String) {  //weblogic
				String str = (String) headerObj;
				str = str.substring(1, str.length() - 1);
				// key=value 쌍 분리
				String[] entries = str.split(",");
				for (String entry : entries) {
				    String[] kv = entry.split("=", 2);
				    if (kv.length == 2) {
				    	inboundHeaderMap.put(kv[0].trim(), kv[1].trim());
				    }
				}
			}	
		} catch (Exception  e) {
		    e.printStackTrace();
		}
		return inboundHeaderMap;
	}

	@Override
	public Object doPostFilter(String adptGrpName, String adptName, Properties prop, Object message,
			Properties tempProp) throws Exception {
		return message;
	}

}
