package com.eactive.eai.transformer.transform;

import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.jdbc.Sql;

import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.transformer.engine.TransformEngine;
import com.eactive.eai.transformer.engine.Transformer;
import com.eactive.eai.transformer.function.jpa.TransformJPATestConfiguration;
import com.eactive.eai.transformer.layout.LayoutManager;
import com.eactive.eai.transformer.layout.LayoutTypeManager;
import com.eactive.eai.transformer.message.JSONMessage;
import com.eactive.eai.transformer.message.Message;
import com.eactive.eai.transformer.message.MessageFactory;

@DataJpaTest
@ContextConfiguration(classes = { TransformJPATestConfiguration.class })
@Sql({ "/com/eactive/eai/transformer/init_tseaitr06.sql", "/com/eactive/eai/transformer/init_tseaitr07.sql",
		"/com/eactive/eai/transformer/init_tseaitr08.sql", "/com/eactive/eai/transformer/init_tseaitr01.sql",
		"/com/eactive/eai/transformer/init_tseaitr02.sql", "/com/eactive/eai/transformer/init_tseaitr03.sql" })
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TransformManagerTest {

	@Autowired
    TransformManager transformManager;

    @Autowired
    LayoutManager layoutManager;

    @Autowired
    LayoutTypeManager layoutTypeManager;

    TransformEngine engine;
    
    boolean initialized = false;
    
    @BeforeEach
    void initOnceAfterSql() throws LifecycleException {
        if (!initialized) {
            layoutTypeManager.start();
            layoutManager.start();
            transformManager.reload();
            engine = TransformEngine.getInstance();
            initialized = true;
        }
    }

	@Test
	void testCase01() throws LifecycleException {

		engine = TransformEngine.getInstance();

		Assert.assertTrue(transformManager.getAllTransformName().length > 0);
		
		String data ="{\r\n"
				+ "    \"data\" : {\r\n"
				+ "        \"cino\" : \"cino_src\",\r\n"
				+ "        \"code\" : \"code\",\r\n"
				+ "        \"listCount\" : 1,\r\n"
				+ "    \"list\" : [\r\n"
				+ "        { \"item1\" : \"1111\", \"item2\" : \"2222\" , \"item3\" : \"3333\"},\r\n"
				+ "        { \"item1\" : \"1111\", \"item2\" : \"2222\" , \"item3\" : \"3333\"},\r\n"
				+ "        { \"item1\" : \"1111\", \"item2\" : \"2222\" , \"item3\" : \"3333\"}\r\n"
				+ "    ]\r\n"
				+ "    }\r\n"
				+ "   \r\n"
				+ "}\r\n"
				+ "";

		
    	Message source = MessageFactory.getFactory().getMessage("TST_TOSSTEST1_SRC");
    	
    	String rootItemName = ((JSONMessage) source).getLayout().getRootItem().getName();

		JSONObject value = (JSONObject) JSONValue.parse(data);
		JSONObject root = new JSONObject();
		root.put(rootItemName, value);
		source.setData(root.toJSONString());
		System.out.println(source.getData());
    	
    	Transformer transformer = engine.getTransformer();
    	Message target = transformer.transform("TRANSFORM_TST_TEST1_REQ", new Message[] { source });
    	
    	System.out.println(target.toString());
    	String testResult = new String((byte[])target.getData());
    	
    	String expectedResult = "cino_code 000031111 2222      3333 1111 2222      3333 1111 2222      3333 ";
	
    	Assert.assertArrayEquals(expectedResult.getBytes(), testResult.getBytes());
	}
	
	@Test
	void testCase02() throws LifecycleException {

		engine = TransformEngine.getInstance();

		Assert.assertTrue(transformManager.getAllTransformName().length > 0);
		
		String data = "{   \"cino\" : \"cino\",\r\n"
				+ "    \"list\" : [\r\n"
				+ "        { \"str\" : \"11111\", \"num\" : 11111 },\r\n"
				+ "        { \"str\" : \"22222\", \"num\" : 22222 },\r\n"
				+ "        { \"str\" : \"33333\", \"num\" : 33333 }\r\n"
				+ "    ],\r\n"
				+ "    \"data\" : 1234\r\n"
				+ "}\r\n"
				+ "";
		
    	Message source = MessageFactory.getFactory().getMessage("TST_TOSSTEST2_SRC");
    	
    	String rootItemName = ((JSONMessage) source).getLayout().getRootItem().getName();

		JSONObject value = (JSONObject) JSONValue.parse(data);
		JSONObject root = new JSONObject();
		root.put(rootItemName, value);
		source.setData(root.toJSONString());
		System.out.println(source.getData());

    	Transformer transformer = engine.getTransformer();
    	Message target = transformer.transform("TRANSFORM_TST_TEST2_REQ", new Message[] { source });
    	
    	System.out.println(target.toString());
    	String testResult = (String) target.getData();
    	String expectedResult = "{\"data\":1234,\"list\":{\"str\":\"11111\",\"num\":\"11111\"},\"cino\":\"cino\"}";
    	
    	Assert.assertArrayEquals(expectedResult.getBytes(), testResult.getBytes());
	}
	
	@Test
	void testCase03() throws LifecycleException {

		engine = TransformEngine.getInstance();

		Assert.assertTrue(transformManager.getAllTransformName().length > 0);
		 	
		String data = "{   \"cino\" : \"cino\",\r\n"
				+ "    \"list\" : [\r\n"
				+ "        { \"str\" : \"11111\", \"num\" : 11111 },\r\n"
				+ "        { \"str\" : \"22222\", \"num\" : 22222 },\r\n"
				+ "        { \"str\" : \"33333\", \"num\" : 33333 }\r\n"
				+ "    ],\r\n"
				+ "    \"data\" : 1234\r\n"
				+ "}\r\n"
				+ "";
		
    	Message source = MessageFactory.getFactory().getMessage("TST_TOSSTEST3_SRC");
    	
    	String rootItemName = ((JSONMessage) source).getLayout().getRootItem().getName();

		JSONObject value = (JSONObject) JSONValue.parse(data);
		JSONObject root = new JSONObject();
		root.put(rootItemName, value);
		source.setData(root.toJSONString());
		System.out.println(source.getData());

    	Transformer transformer = engine.getTransformer();
    	Message target = transformer.transform("TRANSFORM_TST_TEST3_REQ", new Message[] { source });
    	
    	System.out.println(target.toString());
    	String testResult = new String((byte[])target.getData());
    	String expectedResult = "012341111111111cino ";
    	
    	Assert.assertArrayEquals(expectedResult.getBytes(), testResult.getBytes());
	}
	
	@Test
	void testCase04() throws LifecycleException {

		engine = TransformEngine.getInstance();

		Assert.assertTrue(transformManager.getAllTransformName().length > 0);
    	
		String data = "{   \"cino\" : \"cino\",\r\n"
				+ "    \"list\" : \r\n"
				+ "        { \"str\" : \"11111\", \"num\" : 11111 },\r\n"
				+ "    \"data\" : 1234\r\n"
				+ "}\r\n"
				+ "";
		
    	Message source = MessageFactory.getFactory().getMessage("TST_TOSSTEST4_SRC");
    	
    	String rootItemName = ((JSONMessage) source).getLayout().getRootItem().getName();

		JSONObject value = (JSONObject) JSONValue.parse(data);
		JSONObject root = new JSONObject();
		root.put(rootItemName, value);
		source.setData(root.toJSONString());
		System.out.println(source.getData());

    	Transformer transformer = engine.getTransformer();
    	Message target = transformer.transform("TRANSFORM_TST_TEST4_REQ", new Message[] { source });
    	
    	System.out.println(target.toString());
    	String testResult = (String) target.getData();
    	String expectedResult = "{\"data\":1234,\"list\":{\"str\":\"11111\",\"num\":\"11111\"},\"cino\":\"cino\"}";
    	Assert.assertArrayEquals(expectedResult.getBytes(), testResult.getBytes());
	}
	
	@Test
	void testCase05() throws LifecycleException {

		engine = TransformEngine.getInstance();

		Assert.assertTrue(transformManager.getAllTransformName().length > 0);
    	
		String data = "{   \"cino\" : \"cino\",\r\n"
				+ "    \"list\" : \r\n"
				+ "        { \"str\" : \"11111\", \"num\" : 11111 },\r\n"
				+ "    \"data\" : 1234\r\n"
				+ "}\r\n"
				+ "";
		
    	Message source = MessageFactory.getFactory().getMessage("TST_TOSSTEST5_SRC");
    	
    	String rootItemName = ((JSONMessage) source).getLayout().getRootItem().getName();

		JSONObject value = (JSONObject) JSONValue.parse(data);
		JSONObject root = new JSONObject();
		root.put(rootItemName, value);
		source.setData(root.toJSONString());
		System.out.println(source.getData());

    	Transformer transformer = engine.getTransformer();
    	Message target = transformer.transform("TRANSFORM_TST_TEST5_REQ", new Message[] { source });
    	
    	System.out.println(target.toString());
    	String testResult = new String((byte[])target.getData());
    	String expectedResult = "012341111111111cino ";
    	
    	Assert.assertArrayEquals(expectedResult.getBytes(), testResult.getBytes());
	
	}

}
