package com.eactive.eai.message.mapper;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.layout.LayoutReader;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.parser.StandardReader;

public class DefaultMessageMapper implements MessageMapper {

	public StandardMessage parseSub(String msgType, Object message) throws Exception {
		StandardMessageManager standardManager = StandardMessageManager.getInstance();
		StandardMessage subMessage = standardManager.getVersionMessage();
		StandardReader reader = standardManager.getReader(msgType);
		reader.parse(subMessage, message);
		return subMessage;
	}

	public StandardMessage mapFromSub(StandardMessage subMessage, StandardMessage orgStandardMessage) throws Exception {
		StandardMessageManager standardManager = StandardMessageManager.getInstance();
		Map<String, String> mappingMap = standardManager.getVersionMap();
		StandardMessage standardMessage = null;

		if (orgStandardMessage == null) {
			standardMessage = standardManager.getStandardMessage();
		} else {
			standardMessage = orgStandardMessage;
		}

		for (Map.Entry<String, String> entry : mappingMap.entrySet()) {
			map(subMessage, entry.getValue(), standardMessage, entry.getKey());
		}
		return standardMessage;
	}

	// Sub request inbound(100), Sub response outbound(300)
	// parse sub -> mapping to standard
	public StandardMessage mapFromSub(String msgType, Object message, StandardMessage orgStandardMessage)
			throws Exception {
		StandardMessageManager standardManager = StandardMessageManager.getInstance();

		StandardMessage subMessage = parseSub(msgType, message);

		Map<String, String> mappingMap = standardManager.getVersionMap();
		StandardMessage standardMessage = null;

		if (orgStandardMessage == null) {
			standardMessage = standardManager.getStandardMessage();
		} else {
			standardMessage = orgStandardMessage;
		}

		for (Map.Entry<String, String> entry : mappingMap.entrySet()) {
			map(subMessage, entry.getValue(), standardMessage, entry.getKey());
		}
		return standardMessage;
	}

	// Sub response inbound(400), Sub request outbound(200)
	public StandardMessage convertToSub(StandardMessage standardMessage) throws Exception {
		return convertToSub(standardMessage, null);
	}

	public StandardMessage convertToSub(StandardMessage standardMessage, StandardMessage subMessage) throws Exception {
		StandardMessageManager standardManager = StandardMessageManager.getInstance();
		if (subMessage == null) {
			subMessage = standardManager.getVersionMessage();
		}
		Map<String, String> mappingMap = standardManager.getVersionMap();
		// Standard -> Sub
		for (Map.Entry<String, String> entry : mappingMap.entrySet()) {
			map(standardMessage, entry.getKey(), subMessage, entry.getValue());
		}
		return subMessage;
	}

	// Not used until now
	public StandardMessage convertToStandard(StandardMessage subMessage, StandardMessage standardMessage)
			throws Exception {
		StandardMessageManager standardManager = StandardMessageManager.getInstance();
		Map<String, String> mappingMap = standardManager.getVersionMap();
		// Sub -> Standard
		for (Map.Entry<String, String> entry : mappingMap.entrySet()) {
			map(subMessage, entry.getValue(), standardMessage, entry.getKey());
		}
		return standardMessage;
	}

	public void map(StandardMessage sourceMessage, String sourcePath, StandardMessage targetMessage,
			String targetPath) {
		if (sourceMessage == null || StringUtils.isBlank(sourcePath) || targetMessage == null
				|| StringUtils.isBlank(targetPath)) {
			return;
		}
		StandardItem sItem = sourceMessage.findItem(sourcePath);
		StandardItem tItem = targetMessage.findItem(targetPath);
		if (sItem != null && tItem != null) {
			tItem.setValue(sItem.getValue());
		}
	}
}
