package com.eactive.eai.common.security;

import java.util.Map;

import org.springframework.stereotype.Service;

import com.eactive.eai.common.util.ApplicationContextProvider;

/**
 * 어댑터 필터 등에서 암복호화를 위임하는 진입점.
 *
 * STATIC 키 방식:
 *   service.encrypt("MODULE_NAME", plainBytes);
 *
 * DYNAMIC 키 방식 (런타임 컨텍스트 전달):
 *   Map<String,String> ctx = Map.of("X-Api-Enc-Key", request.getHeader("X-Api-Enc-Key"));
 *   service.encrypt("MODULE_NAME", ctx, plainBytes);
 *
 * AAD 명시 방식 (GCM 인증 데이터 전달):
 *   byte[] aad = request.getHeader("X-Api-Request-Id").getBytes(StandardCharsets.UTF_8);
 *   service.encrypt("MODULE_NAME", ctx, aad, plainBytes);
 */
@Service
public class CryptoModuleService {

	public static CryptoModuleService getInstance() {
		return ApplicationContextProvider.getContext().getBean(CryptoModuleService.class);
	}

	// ------------------------------------------------------------------
	// STATIC 키
	// ------------------------------------------------------------------

	public byte[] encrypt(String cryptoName, byte[] plainBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName);
		return ext.encrypt(plainBytes, 0, plainBytes.length);
	}

	public byte[] encrypt(String cryptoName, byte[] aad, byte[] plainBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName);
		return ext.encrypt(plainBytes, 0, plainBytes.length, aad);
	}

	public byte[] decrypt(String cryptoName, byte[] cipherBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName);
		return ext.decrypt(cipherBytes, 0, cipherBytes.length);
	}

	public byte[] decrypt(String cryptoName, byte[] aad, byte[] cipherBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName);
		return ext.decrypt(cipherBytes, 0, cipherBytes.length, aad);
	}

	// ------------------------------------------------------------------
	// DYNAMIC 키
	// ------------------------------------------------------------------

	public byte[] encrypt(String cryptoName, Map<String, String> runtimeContext, byte[] plainBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName, runtimeContext);
		return ext.encrypt(plainBytes, 0, plainBytes.length);
	}

	public byte[] encrypt(String cryptoName, Map<String, String> runtimeContext, byte[] aad, byte[] plainBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName, runtimeContext);
		return ext.encrypt(plainBytes, 0, plainBytes.length, aad);
	}

	public byte[] decrypt(String cryptoName, Map<String, String> runtimeContext, byte[] cipherBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName, runtimeContext);
		return ext.decrypt(cipherBytes, 0, cipherBytes.length);
	}

	public byte[] decrypt(String cryptoName, Map<String, String> runtimeContext, byte[] aad, byte[] cipherBytes) throws Exception {
		CryptoModuleExtension ext = CryptoModuleManager.getInstance().createExtension(cryptoName, runtimeContext);
		return ext.decrypt(cipherBytes, 0, cipherBytes.length, aad);
	}
}
