package com.eactive.eai.rms.common.context;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.rms.common.base.SqlMapClientForMonitoringTemplateDao;
import com.eactive.eai.rms.data.entity.man.monitoringProperty.MonitoringPropertyId;
import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyGroupService;
import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyService;

@Repository("monitoringContextDAO")
@Transactional(transactionManager = "transactionManagerForEMS")
class MonitoringContextDAOImpl extends SqlMapClientForMonitoringTemplateDao implements MonitoringContextDAO {

	@Autowired
	private MonitoringPropertyGroupService monitoringPropertyGroupService;

	@Autowired
	private MonitoringPropertyService monitoringPropertyService;

	@Cacheable("monitoringContextProperties")
	@Override
	public String getProperty(String key, String instancePropertyGroupName) {

		MonitoringPropertyId instancePropertyId = new MonitoringPropertyId();
		instancePropertyId.setPrptyGroupName(instancePropertyGroupName);
		instancePropertyId.setPrptyName(key);

		if (monitoringPropertyService.existsById(instancePropertyId)) {
			// 인스턴스별 프로퍼티 조회
			return monitoringPropertyService.getById(instancePropertyId).getPrpty2Val();
		}

		MonitoringPropertyId commonPropertyId = new MonitoringPropertyId(
				MonitoringPropertyGroupService.MONITORING_PROPERTY_KEY, key);
		if (monitoringPropertyService.existsById(commonPropertyId)) {
			// 공통 프로퍼티 조회
			return monitoringPropertyService.getById(commonPropertyId).getPrpty2Val();
		}

		return null;
	}

	private Optional<String> extractTextInsideBraces(String text) {
		Pattern pattern = Pattern.compile("\\{(.*?)\\}");
		Matcher matcher = pattern.matcher(text);
		return matcher.find() ? Optional.of(matcher.group(1)) : Optional.empty();
	}

	@Override
	public Map<String, String> getPortMap() {
		Map<String, String> portMap = new HashMap<>();

		monitoringPropertyService.findAllByIdPrptyName("WEBSERVERPORT").forEach(prop -> {
			String groupName = prop.getId().getPrptyGroupName();
			extractTextInsideBraces(groupName)
					.ifPresent(instanceName -> portMap.put(instanceName, prop.getPrpty2Val()));
		});

		return portMap;
	}

	@Override
	public Properties getProperties(String instancePropertyGroupName) {
		final Properties properties = new Properties();
		properties.putAll(System.getProperties());

		loadMonitoringProperties(properties, MonitoringPropertyGroupService.MONITORING_PROPERTY_KEY);
		loadInstanceSpecificMonitoringProperties(properties, instancePropertyGroupName);

		return properties;
	}

	private void loadMonitoringProperties(Properties properties, String propertyKey) {
		monitoringPropertyGroupService
				.getById(propertyKey)
				.getMonitoringProperties()
				.forEach(p -> properties.put(p.getId().getPrptyName(), p.getPrpty2Val()));
	}

	private void loadInstanceSpecificMonitoringProperties(Properties properties, String instancePropertyGroupName) {
		monitoringPropertyGroupService
				.findById(instancePropertyGroupName)
				.ifPresent(g -> g
						.getMonitoringProperties()
						.forEach(p -> properties.put(p.getId().getPrptyName(), p.getPrpty2Val())));
	}

}
