package com.eactive.eai.adapter.http.dynamic.filter;

import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;

import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter;
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.message.EAIMessageManager;
import com.eactive.eai.common.stdmessage.STDMessageManager;
import com.eactive.eai.common.stdmessage.STDMsgInfoAddOnVO;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.MessageUtil;
import com.eactive.eai.inbound.action.ActionFactory;
import com.eactive.eai.inbound.action.RequestAction;
import com.eactive.eai.inbound.processor.Processor;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.service.InterfaceMapper;

/**
 * 요청 url를 기반으로 interface id 찾기
 * tx prop에 STD_MESSAGE_KEY, FINAL_STD_MESSAGE_KEY, INTERFACE_ID, EAI_MESSAGE 세팅
 */
public class ApiKeyExtractFilter implements HttpAdapterFilter {
	static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);

	public static final String STD_MESSAGE_KEY = "STD_MESSAGE_KEY";
	public static final String FINAL_STD_MESSAGE_KEY = "FINAL_STD_MESSAGE_KEY";
	public static final String API_SERVICE_CODE = "API_SERVICE_CODE";

	@Override
	public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		String actionName = prop.getProperty(Processor.REQUEST_ACTION);
		RequestAction action = ActionFactory.createAction(actionName);
		action.setAdapterInfo(adptGrpName, adptName, prop);
		String[] keys = action.perform(message);
		String requestPath = keys[0];

		prop.setProperty(STD_MESSAGE_KEY, requestPath);// action class 통해서 생성

		// PathVariable 지원 추가
		String ruledPath = getMatchedKey(requestPath);
		if(ruledPath == null)
			throw new FilterException("path not found - " + requestPath, ERROR_PRE_FAIL, HttpStatus.FORBIDDEN.value());
		prop.setProperty(FINAL_STD_MESSAGE_KEY, ruledPath);// StandardMessageUtil.getMatchedKey(), url
															// pathvariable도 처리
		
		String apiId = prop.getProperty(ApiKeyExtractFilter.FINAL_STD_MESSAGE_KEY);
		if (StringUtils.isBlank(apiId)) {
			throw new JwtAuthException(MessageUtil.ERROR_CODE_AUTH_FAIL, "Can not find apiId(apiCode) info");
		}
		
		String apiSvcCode = this.getEaiSvcCode(apiId);
		prop.put(API_SERVICE_CODE, apiSvcCode);
		
		return message;
	}
	
	private String getEaiSvcCode(String apiId) throws Exception {
		StandardMessage standardMessage = STDMessageManager.getInstance().getSTDMessage(apiId);
		return StandardMessageManager.getInstance().getMapper().getEaiSvcCode(standardMessage);
	}

	@Override
	public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		return resultMessage;
	}
	
	/**
	 * API 서비스에서 실제 요청된 path를 설정된 PathVariable 형태의 key를 찾는다
	 * ex) /api/bank/account/12345 --> /api/bank/account/{accountNo}
	 * @param key
	 * @param actionName
	 * @return
	 */
	public static String getMatchedKey(String key) {
		STDMessageManager stdMessageManager = STDMessageManager.getInstance();
		String[] keys = stdMessageManager.getAllSTDMessageKeys();
		for (String keyStr : keys) {
			if (StringUtils.equals(key, keyStr)) {
				return keyStr;
			}
		}

		return stdMessageManager.getMatchedPathVariable(key);
	}
}
