package org.bench4q.agent.test.scenario;

import static org.junit.Assert.*;

import java.util.Date;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.bench4q.agent.plugin.PluginManager;
import org.bench4q.agent.scenario.Scenario;
import org.bench4q.agent.scenario.engine.ScenarioContext;
import org.bench4q.agent.scenario.engine.Schedule;
import org.bench4q.agent.test.TestBase;
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
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_ScenarioContext extends TestBase {
	@Autowired
	private PluginManager pluginManager;

	@Test
	public void testBuildScenarioContext() {
		ScenarioContext context = buildScenarioContext(UUID.randomUUID(),
				new Scenario(), 20, this.pluginManager);
		assertEquals(10,
				context.getExecutor().getKeepAliveTime(TimeUnit.MINUTES));
		assertEquals(20, context.getExecutor().getMaximumPoolSize());
	}

	@Test
	public void test_AddScenario() {
		ScenarioContext scenarioContext = getScenarioWithScenarioAndSchedule();
		assertNotNull(scenarioContext.getScenario());
		assertEquals(scenarioContext.getStartDate().getTime() + 60 * 1000,
				scenarioContext.getEndDate().getTime());
		assertTrue(scenarioContext.getSchedule().countObservers() > 0);
	}

	private ScenarioContext getScenarioWithScenarioAndSchedule() {
		ScenarioContext scenarioContext = ScenarioContext
				.buildScenarioContextWithoutScenario(UUID.randomUUID(), 100,
						pluginManager);
		scenarioContext = scenarioContext
				.addScenrio(
						Scenario.scenarioBuilderWithCompile(buildRunScenarioModelWith(new LinkedList<UsePluginModel>())),
						Schedule.build(buildScheduleModel()), new Date()
								.getTime());
		return scenarioContext;
	}

	@Test
	public void test_initTasksWithZero() {
		ScenarioContext context = getScenarioWithScenarioAndSchedule();
		context.initTasks(0);
		assertEquals(1, context.getExecutor().getCorePoolSize());
		assertEquals(1, context.getExecutor().getMaximumPoolSize());
	}

	@Test(expected = IllegalArgumentException.class)
	public void test_updatePopulationWithZero() {
		ScenarioContext context = getScenarioWithScenarioAndSchedule();
		context.initTasks(10);
		context.updatePopulation(0);
	}
}
