package org.arefgard.icerya.flow.core;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Map;

import org.arefgard.icerya.flow.exception.UsecaseFlowException;
import org.junit.Test;

import example.flow.nodetest.User;


public class UsecaseFlowTest {
	@Test
	public void executeUsecaseWithS2Container() {
		try {
			UsecaseFlow flow = UsecaseFlowFactory.create("example/flow/seasar2/calc.ucf");
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "+");
			Map<String, Object> rets = flow.executeSync();
			int ret = (Integer)rets.get("return");
			flow.clear();
			assertEquals(150, ret);
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "-");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(50, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "*");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(5000, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "/");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(2, ret);
		}catch(UsecaseFlowException e) {
			e.printStackTrace();
			fail("");
		}catch(Exception e) {
			e.printStackTrace();
			fail("");
		}
	}
	
	@Test
	public void executeUsecaseWithSpring() {
		try {
			UsecaseFlow flow = UsecaseFlowFactory.create("example/flow/spring/calc.ucf");
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "+");
			Map<String, Object> rets = flow.executeSync();
			int ret = (Integer)rets.get("return");
			flow.clear();
			assertEquals(150, ret);
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "-");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(50, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "*");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(5000, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "/");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(2, ret);
		}catch(UsecaseFlowException e) {
			e.printStackTrace();
			fail("");
		}catch(Exception e) {
			e.printStackTrace();
			fail("");
		}
	}
	
	@Test
	public void executeUsecaseWithIcerya() {
		try {
			UsecaseFlow flow = UsecaseFlowFactory.create("example/flow/icerya/calc.ucf");
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "+");
			Map<String, Object> rets = flow.executeSync();
			int ret = (Integer)rets.get("return");
			flow.clear();
			assertEquals(150, ret);
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "-");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(50, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "*");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(5000, ret);
			flow.clear();
			flow.addInput("left", 100);
			flow.addInput("right", 50);
			flow.addInput("expr", "/");
			rets = flow.executeSync();
			ret = (Integer)rets.get("return");
			assertEquals(2, ret);
		}catch(UsecaseFlowException e) {
			e.printStackTrace();
			fail("");
		}catch(Exception e) {
			e.printStackTrace();
			fail("");
		}
	}
	
	@Test
	public void executeUsecaseInherit() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/inherit/super-flow.ucf");
			flow1.addInput("message", "test message.");
			Map<String, Object> rets = flow1.executeSync();
			assertEquals("test message.", rets.get("return"));
			UsecaseFlow flow2 = UsecaseFlowFactory.create("example/flow/inherit/sub-flow.ucf");
			flow2.addInput("message", "test message.");
			rets = flow2.executeSync();
			assertEquals("custom:test message.", rets.get("return"));
		}catch(UsecaseFlowException e) {
			e.printStackTrace();
			fail("");
		}catch(Exception e) {
			e.printStackTrace();
			fail("");
		}
	}
	
	@Test
	public void invokeNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/invoke-test.ucf");
			flow1.executeSync();
		}catch(Exception e) {
			e.printStackTrace();
			fail("");
		}
	}
	
	@Test
	public void throwNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/throw-test.ucf");
			flow1.executeSync();
			fail("failed.");
		}catch(Exception e) {
			assertTrue(true);
		}
	}
	
	@Test
	public void loadNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/load-test.ucf");
			Map<String, Object> rets = flow1.executeSync();
			User user = (User)rets.get("var1");
			assertNotNull(user);
			assertEquals("Taro", user.getName());
			assertEquals(100, user.getAge());
		}catch(Exception e) {
			e.printStackTrace();
			fail("failed.");
			
		}
	}
	
	@Test
	public void includeNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/include-test.ucf");
			Map<String, Object> rets = flow1.executeSync();
			User user = (User)rets.get("var1");
			assertNotNull(user);
			assertEquals("Taro", user.getName());
			assertEquals(500, user.getAge());
		}catch(Exception e) {
			e.printStackTrace();
			fail("failed.");
			
		}
	}
	
	@Test
	public void whileNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/while-test.ucf");
			Map<String, Object> rets = flow1.executeSync();
			int value = (Integer)rets.get("var1");
			assertEquals(10, value);
		}catch(Exception e) {
			e.printStackTrace();
			fail("failed.");
			
		}
	}
	
	@Test
	public void syncNodeTest1() {
		try {
			UsecaseFlow flow1 = UsecaseFlowFactory.create("example/flow/nodetest/sync-test.ucf");
			flow1.executeAsync();
			while(!flow1.isFinished()) {
				//
			}
		}catch(Exception e) {
			e.printStackTrace();
			fail("failed.");
			
		}
	}
	
}
