package com.eactive.eai.message.test;

import java.util.ArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.eactive.eai.message.StandardItem;
import com.eactive.eai.message.StandardMessage;
import com.eactive.eai.message.StandardMessageUtil;
import com.eactive.eai.message.StandardType;
import com.eactive.eai.message.manager.StandardMessageManager;
import com.eactive.eai.message.parser.StandardReader;
import com.eactive.eai.message.parser.XmlReader;

public class SrandardMessageTest {
	static Logger logger = LoggerFactory.getLogger(SrandardMessageTest.class);
	static String strString =
	"000199GIDNO00000000004444          ELINKSVC01ELINK TEST Service                                                                                  SSESSIONID001                                                                                        NO                                                                                                    SCREEN0000001000000000100000000020000000003                                                                                                    USER000001                                                           EACTEACT001ELINK01CHEA20220928000000000                 S                                                                                                                                                                                                                                                                                                                                                                                               TESTSET-BIZDATA";

	static String jsonString =
		"{"
	+ "  \"msg_len\":199,"
	+ "  \"global_id\":\"GIDNO00000000002222\","
	+ "  \"service_id\":\"ELINKSVC01\","
	+ "  \"service_cmt\":\"ELINK TEST Service\","
	+ "  \"service_tn\":\"S\","
	+ "  \"Session_id\":\"SESSIONID001\","
	+ "  \"encrypt_yn\":\"NO\","
	+ "  \"http_url\":\"\","
	+ "  \"screen_id\":\"SCREEN0000001\","
	+ "  \"scr_no\":\"000000000100000000020000000003\","
	+ "  \"scr_dsc\":\"\","
	+ "  \"usr_id\":\"USER000001\","
	+ "  \"ip_addr\":\"\","
	+ "  \"ip_mac\":\"\","
	+ "  \"com_code\":\"EACT\","
	+ "  \"head_code\":\"EACT001\","
	+ "  \"dept_cd\":\"ELINK01\","
	+ "  \"conn_tp\":\"CH\","
	+ "  \"Inter_chn\":\"EA\","
	+ "  \"recv_tm\":\"20220928000000000\","
	+ "  \"send_tm\":\"\","
	+ "  \"return_gubun\":\"S\","
	+ "  \"return_value\":\"\","
	+ "  \"msg_id\":\"\","
	+ "  \"msg_nm\":\"\","
	+ "  \"filler\":\"\","
	+ "  \"bizData\":{"
		+ "  \"bizfield1\":\"BIZ1\","
		+ "  \"bizfield2\":\"BIZ2\","
		+ "  \"bizfield3\":\"BIZ3\""
	+ "  }"
	+ "}";
	
	static String xmlString = 
		"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
		+ "<Root>"
		+ "  <msg_len>199</msg_len>"
		+ "  <global_id>GIDNO00000000003333</global_id>"
		+ "  <service_id>ELINKSVC01</service_id>"
		+ "  <service_cmt>ELINK TEST Service</service_cmt>"
		+ "  <service_tn>S</service_tn>"
		+ "  <Session_id>SESSIONID001</Session_id>"
		+ "  <encrypt_yn>NO</encrypt_yn>"
		+ "  <http_url></http_url>"
		+ "  <screen_id>SCREEN0000001</screen_id>"
		+ "  <scr_no>000000000100000000020000000003</scr_no>"
		+ "  <scr_dsc></scr_dsc>"
		+ "  <usr_id>USER000001</usr_id>"
		+ "  <ip_addr></ip_addr>"
		+ "  <ip_mac></ip_mac>"
		+ "  <com_code>EACT</com_code>"
		+ "  <head_code>EACT001</head_code>"
		+ "  <dept_cd>ELINK01</dept_cd>"
		+ "  <conn_tp>CH</conn_tp>"
		+ "  <Inter_chn>EA</Inter_chn>"
		+ "  <recv_tm>20220928000000000</recv_tm>"
		+ "  <send_tm></send_tm>"
		+ "  <return_gubun>S</return_gubun>"
		+ "  <return_value></return_value>"
		+ "  <msg_id></msg_id>"
		+ "  <msg_nm></msg_nm>"
		+ "  <filler></filler>"
		+ "  <bizData><message><bizfield1>BIZ1</bizfield1><bizfield2>BIZ2</bizfield2><bizfield3>BIZ3</bizfield3></message></bizData>"
		+ "</Root>";
	
	public SrandardMessageTest() {

	}
	
	public static StandardMessage generateMessage() {
//		return StandardMessageUtil.generateMessageFromCCsvFile();
		StandardMessageManager manager = StandardMessageManager.getInstance();
		try {
			manager.init();
		}
		catch(Exception ex) {
			ex.printStackTrace();
			return null;
		}
		return manager.getStandardMessage();
	}
	
	
	public static StandardMessage generateMessageFromItemList() {
		// Test generator from List definition (with default values)
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		logger.debug(">> Test generator from List definition ( with default values)");
		ArrayList<StandardItem> list = new ArrayList<StandardItem>();
		StandardItem group = null;
		StandardItem item = null;
		group = new StandardItem("Header", 1, StandardType.GROUP, 1, 0, 0, null);
		list.add(group);
		item = new StandardItem("StndCicsTrncd", 2, StandardType.FIELD, 1, 10, 0, "");
		list.add(item);
		item = new StandardItem("StndIntnlStndTelgmLen", 2, StandardType.FIELD, 1, 10, 1, "0");
		list.add(item);
		item = new StandardItem("StndTranBaseYmd", 2, StandardType.FIELD, 1, 10, 0, "");
		list.add(item);

		StandardItem group1 = new StandardItem("Common", 1, StandardType.GROUP, 0, 0, null);
		list.add(group1);
		group = new StandardItem("TranInfo", 2, StandardType.GROUP, 0, 0, null);
		list.add(group);
		item = new StandardItem("StndCicsTrncd", 3, StandardType.FIELD, 3, 0, "KB0");
		list.add(item);
		item = new StandardItem("StndTelgmRecvTranCd", 3, StandardType.FIELD, 10, 0, "");
		list.add(item);
		item = new StandardItem("StndPrcssRtdTranCd", 3, StandardType.FIELD, 10, 0, "");
		list.add(item);
		
		group = new StandardItem("Array", 1, StandardType.GRID, 3, 0, null);
		list.add(group);
		item = new StandardItem("Item1", 2, StandardType.FIELD, 10, 0, "JI6H");
		list.add(item);
		item = new StandardItem("Group", 2, StandardType.GRID, 1, 0, null);
		list.add(item);
		item = new StandardItem("gitem1", 3, StandardType.FIELD, 10, 1, "726");
		list.add(item);
		item = new StandardItem("gitem2", 3, StandardType.FIELD, 10, 0, "20220905");
		list.add(item);
		
		item = new StandardItem("bizData", 1, StandardType.BIZDATA, 0, 0, null);
		list.add(item);
		
		StandardMessage message = null;;
		try {
			message = StandardMessageUtil.generate(list);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
		// TODO
		// 1. CSV -> List -> gen
		// 2. XML -> List -> gen
		// 3. JSON -> List -> gen
		logger.debug("@toCSVString\n" + message.toCSVString());
		logger.debug("@toString\n" + message.toString());
		logger.debug("@toJson\n" + message.toJson());
		
		// Test initialize getter
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		logger.debug(">> Test initialize getter");
		String findItem = "StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Header.StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Common.TranInfo.StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		logger.debug(">> Test file item with path & set value");
		StandardItem it = message.findItem(findItem);
		if(it !=null) {
			it.setValue("changed!");
		}
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Common.TranInfo.StndCicsTrncd1";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Array[0].Group.gitem2";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Array[0]";
		logger.debug(findItem + " => " +message.findItem(findItem));
		
		return message;
	}
	
	public static void testJsonReader() throws Exception {
		StandardMessage message = null;;
		message = generateMessage();
		if(message == null) {
			return;
		}
		
		logger.debug(">> Test Json Parsing");
		
		logger.debug("jsonString = " +jsonString);
		
		// Test Json parsing
//		StandardReader jsonReader = new JsonReader();
		
		// Test Dynamic Loading
		StandardReader reader = null;
		String readerName = "com.eactive.eai.message.parser.JsonReader";
		Class cl = null;
		try {
			cl = Class.forName(readerName);
			reader = (StandardReader)cl.newInstance();
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
			return;
		}
		reader.parse(message, jsonString);
		
		String charset = "utf-8";
		message.setBizDataCharset(charset);
		logger.debug(">> message=\n" + message);
		logger.debug(">> message.toJson()=\n" + message.toJson());
		logger.debug(">> message.toJson(false)=\n" + message.toJson(false));
		logger.debug(">> message.toPrettyJson()=\n" + message.toPrettyJson());
		logger.debug(">> message.toPrettyJson(false)=\n" + message.toPrettyJson(false));
		logger.debug(">> message.toXML()=\n" + message.toXML());
		logger.debug(">> message.toPrettyXML()=\n" + message.toPrettyXML());
		logger.debug(">> message.toFixedString()=\n[" + message.toFixedString(charset)+"]");
		logger.debug(">> message.toByteArray()=\n[" + new String(message.toByteArray(charset)) + "]");
		logger.debug(">> message.toLogList()=\n" + message.toLogList());
		// Test getter after parsing
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		String findItem = null;
		logger.debug(">> Test getter after parsing");
		findItem = "global_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "Session_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "screen_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));		
		findItem = "recv_tm";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
	}
	
	public static void testXmlReader() throws Exception {
		StandardMessage message = null;;
		message = generateMessage();
		if(message == null) {
			return;
		}
		
		logger.debug(">> Test Json Parsing");
		
		logger.debug("xmlString = " + xmlString);
		
		// Test XML parsing
		StandardReader reader = new XmlReader();
		reader.parse(message, xmlString);
		
		logger.debug(">> message=\n" + message);
		logger.debug(">> message.toJson()=\n" + message.toJson());
		logger.debug(">> message.toXML()=\n" + message.toXML());
		// Test getter after parsing
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		String findItem = null;
		logger.debug(">> Test getter after parsing");
		findItem = "global_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "Session_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "screen_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));		
		findItem = "recv_tm";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
	}
	
	
	public static void testDynamicReader(String messageType, String messageString) throws Exception {
		StandardMessage message = null;
		message = generateMessage();
		if(message == null) {
			return;
		}
		
		logger.debug(">> Test Parsing");
		
		logger.debug("messageString = " +messageString);
		
		// Test Json parsing
		// Test Dynamic Loading
		StandardReader reader = null;
		
		StandardMessageManager manager = StandardMessageManager.getInstance();
		
		reader = manager.getReader(messageType);

		reader.parse(message, messageString);
		
		String charset = "utf-8";
		
		logger.debug(">> message=\n" + message);
		logger.debug(">> message.toByteArray()=\n" + new String(message.toByteArray(charset)));
		logger.debug(">> message.toJson()=\n" + message.toJson());
		logger.debug(">> message.toPrettyJson()=\n" + message.toPrettyJson());
		logger.debug(">> message.toXML()=\n" + message.toXML());
		logger.debug(">> message.toPrettyXML()=\n" + message.toPrettyXML());
		
		logger.debug(">> message.setBizData() to TESTSET-DATA");
		message.setBizData("TESTSET-DATA", "utf-8");
		logger.debug(">> message.toByteArray()=\n[" + new String(message.toByteArray(charset)) +"]");
		// Test getter after parsing
		logger.debug("\n>> ----------------------------------------------------------------------------------");
		String findItem = null;
		logger.debug(">> Test getter after parsing");
		findItem = "global_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "Session_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		findItem = "screen_id";
		logger.debug(findItem + " => " +message.findItemValue(findItem));		
		findItem = "recv_tm";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
	}
	
	public static void testSimple() {
		int level = 0;
		StandardMessage message = new StandardMessage();
		StandardItem group = null;
		StandardItem item = null;
		level++;
		group = new StandardItem("Header", level, 2, 0, 0, null);
		level++;
		item = new StandardItem("StndCicsTrncd", level, 1, 10, 0, "JI6H");
		group.addItem(item);
		item = new StandardItem("StndIntnlStndTelgmLen", level, 1, 10, 1, "726");
		group.addItem(item);
		item = new StandardItem("StndTranBaseYmd", level, 1, 10, 0, "20220905");
		group.addItem(item);
		message.addItem(group);
		
		level--;
		StandardItem group1 = new StandardItem("Common", level, 2, 0, 0, null);
		level++;
		group = new StandardItem("TranInfo", level, 2, 0, 0, null);
		level++;
		item = new StandardItem("StndCicsTrncd", level, 1, 10, 0, "KB0");
		group.addItem(item);
		item = new StandardItem("StndTelgmRecvTranCd", level, 1, 10, 0, "EDU0100101");
		group.addItem(item);
		item = new StandardItem("StndPrcssRtdTranCd", level, 1, 10, 0, "JI6HWSE02002");
		group.addItem(item);
		group1.addItem(group);
		message.addItem(group1);
		
		logger.debug(">> toString");
		logger.debug(message.toString());
		logger.debug(">> toCSVString");
		logger.debug(message.toCSVString());
		logger.debug(">> toJson");
		logger.debug(message.toJson());
		
		String findItem = "StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Header.StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Common.TranInfo.StndCicsTrncd";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
		
		findItem = "Common.TranInfo.StndCicsTrncd1";
		logger.debug(findItem + " => " +message.findItemValue(findItem));
	}
	
	public static void splitTest(String path, String pathSeparator) {
		String[] paths = null;
		logger.debug("path=" + path);
		logger.debug("pathSeparator=" + pathSeparator);
		
		paths = path.split("[" + pathSeparator +"]");
		int index =0;
		for(String p: paths) {
			System.out.printf("path[%d]=(%s)\n", index++, p);
		}
	}
	
	public static void testFlatReader( int caseNumber) {
		String testString = null; 
		
		if( caseNumber == 1) {
			testString ="000199GIDNO00000000004444          ELINKSVC01ELINK TEST Service                                                                                  SSESSIONID001                                                                                        NO                                                                                                    SCREEN0000001000000000100000000020000000003                                                                                                    USER000001                                                           EACTEACT001ELINK01CHEA20220928000000000                 S                                                                                                                                                                                                                                                                                                                                                                                               @@";
			try {
				testDynamicReader("FLAT", testString);
			}
			catch(Exception ex) {
				logger.debug("success test : " + ex.toString());
			}
		}
		
		// underflow
		if( caseNumber == 2) {
			testString ="000199GIDNO00000000004444          ELINKSVC01ELINK TEST Service                                                                                  SSESSIONID001                                                                                        NO                                                                                                    SCREEN0000001000000000100000000020000000003                                                                                                    USER000001                                                           EACTEACT001ELINK01CHEA20220928000000000                 S                                                                                                                                                                                                                                                                                                                                                                                     @@";
			try {
				testDynamicReader("FLAT", testString);
			}
			catch(Exception ex) {
				logger.debug("underflow test : " + ex.toString());
			}
		}
		// with bizData
		if( caseNumber == 3) {
			testString ="001005GIDNO00000000004444          ELINKSVC01ELINK TEST Service                                                                                  SSESSIONID001                                                                                        NO                                                                                                    SCREEN0000001000000000100000000020000000003                                                                                                    USER000001                                                           EACTEACT001ELINK01CHEA20220928000000000                 S                                                                                                                                                                                                                                                                                                                                                                                               ADDED@@";
			try {
				testDynamicReader("FLAT", testString);
			}
			catch(Exception ex) {
				logger.debug("overflow test : " + ex.toString());
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
//		testSimple();

//		testJsonReader();
//		testXmlReader();
		testFlatReader(1);
//		testFlatReader(2);
//		testFlatReader(3);
		
//		testDynamicReader("JSON", jsonString);
//		testDynamicReader("XML", xmlString);
//		generateMessageFromItemList();		
	}

}
