package org.bench4q.agent.test.scenario;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.bench4q.agent.scenario.Parameter;
import org.bench4q.agent.scenario.Scenario;
import org.bench4q.agent.scenario.behavior.Behavior;
import org.bench4q.agent.scenario.dfa.ParamPart;
import org.bench4q.agent.scenario.dfa.ParamPart.ParamPartType;
import org.bench4q.agent.test.TestBase;
import org.bench4q.share.helper.MarshalHelper;
import org.bench4q.share.helper.TestHelper;
import org.bench4q.share.models.agent.ParameterModel;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:application-context.xml" })
public class Test_Scenario extends TestBase {
	private static final String TEST_CASE = "${csvProvider0:userName}$#okOrNot${file.separator}";

	@Test
	public void test_GenerateMongoScenario() throws IOException {
		BehaviorModel[] behaviors = new BehaviorModel[28];
		for (int i = 0; i < 9; i++) {
			behaviors[3 * i] = BehaviorModel
					.ControlBehaviorBuilder(3 * i, "Sleep", "Timer_0", Arrays
							.asList(ParameterModel
									.createParameter("time", "10")));
			behaviors[3 * i + 1] = BehaviorModel.TimerBehaviorBuilder(
					3 * i + 1, "Set", "Context_0", Arrays.asList(ParameterModel
							.createParameter("toSave", "${UUID_0:var}")));
			behaviors[3 * i + 2] = BehaviorModel
					.UserBehaviorBuilder(
							3 * i + 2,
							"Insert",
							"MongoDBPlugin_0",
							Arrays.asList(
									ParameterModel.createParameter("key",
											"${UUID_0:var}"),
									ParameterModel
											.createParameter(
													"value",
													"828731929090399688663513844419156517791913487136162075054396888608979390802698967398774976538053071265086303536432973027547398485897859650637839199967916419278859657562410371550970990533755543895317958490879810955359859803793616914752497927102101107393602107374624265703167902037562601756290624400217677905796841586506540830996528039667809341170671731917392828543425909887469350859806312812589702773082295018742634842159778009485901428286815715514440370336211621120027294867866046842579395402354849290925687231979896816952130161564546780855710443002842992917011602246580128072986737704758180050405202976240171827695507627799312781883033823819663102843159141022325482803101497005554269652897365593399081219143594918151989844361363454642099858085072470136971359171934346214072016627940215525657780835264287095014748952849011967941296078931973149033644269161629346531549579584063826798825958153903463232155174301997795504543310963155667642944030315802981522872371957377604512253881055347955240594154853114826089693318722619283530276507503")));
		}
		behaviors[27] = BehaviorModel.TimerBehaviorBuilder(28, "Sleep",
				"Timer_0",
				Arrays.asList(ParameterModel.createParameter("time", "1000")));
		RunScenarioModel runScenarioModel = buildRunScenarioModelWith(
				Arrays.asList(
						new UsePluginModel("Timer_0", "ConstantTimer",
								Collections.<ParameterModel> emptyList()),
						new UsePluginModel("UUID_0", "UUID", null),
						new UsePluginModel("Context_0", "Context", null),
						new UsePluginModel("MongoDBPlugin_0", "MongoDBPlugin",
								Arrays.asList(ParameterModel.createParameter(
										"hostName", "133.133.13.154"),
										ParameterModel.createParameter("port",
												"27017"), ParameterModel
												.createParameter("dbName",
														"temp")))), behaviors);
		File file = new File("Scripts" + System.getProperty("file.separator")
				+ "mongo9To1.xml");
		TestHelper.createFileIfNotExist(file);
		FileUtils.writeStringToFile(file,
				MarshalHelper.tryMarshal(runScenarioModel));
		createVUser(Scenario.scenarioBuilderWithCompile(runScenarioModel),
				UUID.randomUUID()).run();
	}

	@Test
	public void test_generateHTTPScenario() throws IOException {
		BehaviorModel[] behaviors = new BehaviorModel[10];
		for (int i = 0; i < 10; i++) {
			behaviors[i] = BehaviorModel.UserBehaviorBuilder(3 * i + 2, "Get",
					"HTTP_0", Arrays.asList(ParameterModel.createParameter(
							"url", "http://58.211.191.47:8080/")));
		}
		RunScenarioModel runScenarioModel = buildRunScenarioModelWith(
				Arrays.asList(new UsePluginModel("Timer_0", "ConstantTimer",
						Collections.<ParameterModel> emptyList()),
						new UsePluginModel("Context_0", "Context", null),
						new UsePluginModel("HTTP_0", "Http",
								new ArrayList<ParameterModel>())), behaviors);
		File file = new File("Scripts" + System.getProperty("file.separator")
				+ "testBalance.xml");
		TestHelper.createFileIfNotExist(file);
		FileUtils.writeStringToFile(file,
				MarshalHelper.tryMarshal(runScenarioModel));
		createVUser(Scenario.scenarioBuilderWithCompile(runScenarioModel),
				UUID.randomUUID()).run();
	}

	@Test
	public void test_ScenarioCompile() {
		RunScenarioModel inputModel = buildRunScenarioModelWith(
				new ArrayList<UsePluginModel>(),
				BehaviorModel.UserBehaviorBuilder(0, "first", "http",
						new ArrayList<ParameterModel>() {
							private static final long serialVersionUID = 1L;
							{
								add(ParameterModel.createParameter(
										"withParamPart", TEST_CASE));
							}
						}));
		Scenario scenario = Scenario.scenarioBuilderWithCompile(inputModel);
		for (Behavior behavior : scenario.getAllBehaviors()) {
			assertEquals("first", behavior.getName());
			assertEquals(0, behavior.getId());
			assertEquals("http", behavior.getUse());
			for (Parameter parameter : behavior.getParameters()) {
				assertNotNull(parameter.getParamParts());
				List<ParamPart> result = Arrays.asList(parameter
						.getParamParts());
				assertEquals(4, result.size());
				assertEquals("csvProvider0", result.get(0)
						.getPluginIdForContextCallType());
				assertEquals(ParamPartType.CONTEXT_CALL, result.get(0)
						.getType());
				assertEquals("userName", result.get(0)
						.getVariableForContextCallAndProperty());
				assertNull(result.get(0).getContentForStringType());

				assertEquals(ParamPartType.SESSION_ID, result.get(1).getType());
				assertNull(result.get(1).getContentForStringType());
				assertNull(result.get(1).getPluginIdForContextCallType());
				assertNull(result.get(1).getVariableForContextCallAndProperty());

				assertEquals(ParamPartType.STRING, result.get(2).getType());
				assertNull(result.get(2).getPluginIdForContextCallType());
				assertNull(result.get(2).getVariableForContextCallAndProperty());
				assertEquals("okOrNot", result.get(2).getContentForStringType());

				assertEquals(ParamPartType.PROPERTY, result.get(3).getType());
				assertNull(result.get(3).getPluginIdForContextCallType());
				assertNull(result.get(3).getContentForStringType());
				assertEquals("file.separator", result.get(3)
						.getVariableForContextCallAndProperty());
			}
		}
	}

}
