package org.bench4q.master.unitTest.service;

import static org.junit.Assert.*;

import java.util.Set;
import java.util.UUID;

import org.bench4q.master.domain.entity.TestPlan;
import org.bench4q.master.domain.entity.TestPlanScript;
import org.bench4q.master.domain.entity.User;
import org.bench4q.master.unitTest.TestBase_MakeUpTestPlan;
import org.bench4q.share.enums.master.TestPlanStatus;
import org.bench4q.share.models.master.TestPlanResultModel;
import org.junit.After;
import org.junit.Before;
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:service-test-context.xml" })
public class Test_TestPlanService extends TestBase_MakeUpTestPlan {

	@Test
	public void testLoadTestPlans() {
		assertTrue(this.getTestPlanService()
				.loadTestPlans(this.getUserRepository().getUser("admin"))
				.size() > 0);
	}

	@Test
	public void testQueryTestPlanStatus() {
		assertEquals(TestPlanStatus.NotStart, this.getTestPlanService()
				.queryTestPlanStatus(getTestPlanRunIdUuid()));
	}

	@Test
	public void testRemoveTestPlanInDB() {
		int planCountBeforeSubmit = this.getTestPlanRepository()
				.loadEntities(this.getUserRepository().getUser("admin")).size();
		submitATestPlanWithOneScript();
		int planCountBetweenSubmitAndRemove = this.getTestPlanRepository()
				.loadEntities(this.getUserRepository().getUser("admin")).size();
		assertEquals(planCountBeforeSubmit + 1, planCountBetweenSubmitAndRemove);
	}

	@Test
	public void testSaveTestPlanToDB() {
		User user = this.getUserRepository().getUser("admin");
		int planCountBeforeSubmit = this.getTestPlanRepository()
				.loadEntities(user).size();
		System.out.println(planCountBeforeSubmit);
		UUID randomUUID = UUID.randomUUID();
		assertTrue(this.getTestPlanEngine().submitTestPlan(
				createATestPlanWithOneScript(getUserFirstScript(user)), user,
				randomUUID));
		int planCountAfterSubmit = this.getTestPlanRepository()
				.loadEntities(user).size();
		assertEquals(planCountBeforeSubmit + 1, planCountAfterSubmit);
		TestPlan testPlan = this.getTestPlanRepository().getTestPlanInDomainBy(
				randomUUID);
		Set<TestPlanScript> testPlanScripts = testPlan.getTestPlanScripts();
		assertNotNull(testPlanScripts);
		assertEquals(1, testPlanScripts.size());
		assertNotNull(testPlan.getMonitors());
		assertEquals(1, testPlan.getMonitors().size());
		for (TestPlanScript testPlanScript : testPlanScripts) {
			assertEquals(getScriptId(), testPlanScript.getScript().getId());
			assertEquals(20, testPlanScript.getPlanedConfig().getWarmUp());
		}
		assertTrue(this.getTestPlanRepository().detach(testPlan.getId()));
	}

	@Test
	public void testSaveTestPlanWithTwoScript() {
		this.getTestPlanRepository().detach(
				this.getTestPlanRepository()
						.getTestPlanInDomainBy(getTestPlanRunIdUuid()).getId());
		User user = this.getUserRepository().getUser("admin");
		int initialTestPlanSize = this.getTestPlanRepository()
				.loadEntities(user).size();
		submitATestPlanWithTwoScript();
		int sizeAfterSubmitTestPlanWithTwoScript = this.getTestPlanRepository()
				.loadEntities(user).size();
		assertEquals(initialTestPlanSize + 1,
				sizeAfterSubmitTestPlanWithTwoScript);
	}

	@Test
	public void testBuildResponseModel() {
		TestPlanResultModel responseModel = this.getTestPlanService()
				.buildResultModel(getTestPlanRunIdUuid());
		assertEquals(1, responseModel.getScripts().size());
		assertEquals(1, responseModel.getMonitorModels().size());
		assertEquals(getTestPlanRunIdUuid(), responseModel.getTestPlanId());
	}

	@Before
	public void prepare() {
		submitATestPlanWithOneScript();
	}

	@After
	public void cleanUp() {
		this.getTestPlanRepository().detach(
				this.getTestPlanRepository()
						.getTestPlanInDomainBy(getTestPlanRunIdUuid()).getId());
	}
}
