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

import java.util.Base64;
import java.util.Properties;

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

import org.json.simple.JSONObject;
import org.springframework.http.HttpStatus;

import com.eactive.eai.adapter.http.dynamic.filter.FilterException;
import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter;
import com.eactive.eai.common.security.AESCryptoModuleExtension;
import com.eactive.eai.common.security.ARIACryptoModuleExtension;
import com.eactive.eai.common.security.CryptoModuleExtension;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.util.HexaConverter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class DecrytTestFilter implements HttpAdapterFilter {

	private static final Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);

	private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

	@Override
	public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			ObjectNode rootNode = null;
			String jsonStr = null;
			if (message instanceof String) {
				jsonStr = (String) message;
			} else if (message instanceof JSONObject) {
				jsonStr = ((JSONObject) message).toJSONString();
			} else {
				return message;
			}
			rootNode = (ObjectNode) OBJECT_MAPPER.readTree(jsonStr);

			JsonNode alg = rootNode.get("alg");
			JsonNode mode = rootNode.get("mode");
			JsonNode padding = rootNode.get("padding");
			JsonNode aadNode = rootNode.get("aad");
			JsonNode iv = rootNode.get("iv");
			byte[] binIv = null;
			if(iv != null) {
				String strIv = iv.asText();
				binIv = HexaConverter.hexToBin(strIv);
			}
			JsonNode encKey = rootNode.get("encKey");
			String strEncKey = encKey.asText();
			byte[] binEncKey = HexaConverter.hexToBin(strEncKey);

			CryptoModuleExtension ext = "ARIA".equalsIgnoreCase(alg.asText()) ? new ARIACryptoModuleExtension()
					: new AESCryptoModuleExtension();
			ext.init(alg.asText(), mode.asText(), padding.asText(), binIv, binEncKey, binEncKey);

			JsonNode encryptedData = rootNode.get("encryptedData");
			byte[] cipherBytes = Base64.getDecoder().decode(encryptedData.asText().trim());
			
			byte[] decryptedBytes = null;
			if(rootNode.has("aad"))
				decryptedBytes = ext.decrypt(cipherBytes, HexaConverter.hexToBin(aadNode.asText()));
			else
				decryptedBytes = ext.decrypt(cipherBytes);
			
			rootNode.put("hsmKeyRaw", new String(decryptedBytes));

			String jsonString = OBJECT_MAPPER.writeValueAsString(rootNode);
			return jsonString;

		} catch (Exception e) {
			logger.error("복호화 실패", e);
			throw new FilterException("복호화 실패", ERROR_PRE_FAIL, HttpStatus.INTERNAL_SERVER_ERROR.value(), e);
		}
	}

	@Override
	public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		return resultMessage;
	}

}
