package org.bench4q.master.unitTest.service;

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import javax.xml.bind.JAXBException;
import org.apache.commons.io.FileUtils;
import org.bench4q.master.domain.entity.Script;
import org.bench4q.master.domain.entity.User;
import org.bench4q.master.domain.repository.UserRepository;
import org.bench4q.master.domain.service.ScriptService;
import org.bench4q.master.domain.service.UserService;
import org.bench4q.share.helper.MarshalHelper;
import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.PageModel;
import org.junit.After;
import org.junit.Before;
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:mockHttpMesseger-context.xml" })
public class Test_ScriptService {
	private ScriptService scriptService;
	private UserService userService;
	private UserRepository userRepository;
	private User userForTest;

	private ScriptService getScriptService() {
		return scriptService;
	}

	@Autowired
	private void setScriptService(ScriptService scriptService) {
		this.scriptService = scriptService;
	}

	private UserService getUserService() {
		return userService;
	}

	@Autowired
	private void setUserService(UserService userService) {
		this.userService = userService;
	}

	private UserRepository getUserRepository() {
		return userRepository;
	}

	@Autowired
	private void setUserRepository(UserRepository userRepository) {
		this.userRepository = userRepository;
	}

	private User getUserForTest() {
		return userForTest;
	}

	private void setUserForTest(User userForTest) {
		this.userForTest = userForTest;
	}

	@Test
	public void testSaveScript() throws JAXBException {
		User user = this.getUserRepository().getUser("test1");
		assertNotNull(user);
		assertTrue(doSaveAScript(user));
	}

	@Test
	public void testSaveScriptWithDefinedParameters() throws IOException {
		User user = this.getUserForTest();
		String fileSeparator = System.getProperty("file.separator");
		assertTrue(this.getScriptService().saveScript(
				"goodRecord",
				user.getId(),
				FileUtils.readFileToString(new File("Scripts" + fileSeparator
						+ "forGoodRecord.xml")), null));
	}

	private void guardAdminExist() {
		this.getUserService().register("admin", "admin", (byte) 1);
	}

	private boolean doSaveAScript(User user) throws JAXBException {
		return this.getScriptService().saveScript(
				"ad",
				user.getId(),
				MarshalHelper.marshal(RunScenarioModel.class,
						new RunScenarioModel()), null);
	}

	@Before
	public void prepare() {
		guardAdminExist();
		this.getUserService().register("test1", "test1", (byte) 1);
		this.setUserForTest(this.getUserRepository().getUser("test1"));
	}

	@Test
	public void testLoadScripts() throws JAXBException {
		User user = this.getUserRepository().getUser("test1");
		assertNotNull(user);
		assertTrue(this.getScriptService().saveScript(
				"adef",
				user.getId(),
				MarshalHelper.marshal(RunScenarioModel.class,
						new RunScenarioModel()), null));
		assertEquals(1, this.getScriptService().loadScripts(user).size());
	}

	@Test
	public void testGetScript() throws JAXBException {
		User user = this.getUserRepository().getUser("test1");
		doSaveAScript(user);
		Script script = this.getScriptService().getScript(
				getUploadScriptId(user));
		assertNotNull(script);
		assertEquals("test1", script.getUser().getUserName());
	}

	private int getUploadScriptId(User user) {
		return this.getScriptService().loadScripts(user).get(0).getId();
	}

	@Test
	public void testQueryScriptsByCreateTime() throws JAXBException {
		this.doSaveAScript(this.getUserForTest());
		List<Script> result = this.getScriptService().queryScriptsByCreateTime(
				new Date(0), new Date(), this.getUserForTest());
		assertEquals(1, result.size());
	}

	@Test
	public void testUpdateScript() throws JAXBException {
		doSaveAScript(getUserForTest());
		RunScenarioModel runScenarioModel = new RunScenarioModel();
		runScenarioModel.setPages(new LinkedList<PageModel>() {
			private static final long serialVersionUID = 1L;
			{
				add(new PageModel(1));
			}
		});
		assertTrue(this.getScriptService()
				.alterScriptContent(
						getUploadScriptId(getUserForTest()),
						getUserForTest().getId(),
						MarshalHelper.marshal(RunScenarioModel.class,
								runScenarioModel),"test"));
		String content = this.getScriptService()
				.getScript(getUploadScriptId(getUserForTest()))
				.getScriptContent();
		RunScenarioModel afterUpdate = (RunScenarioModel) MarshalHelper
				.unmarshal(RunScenarioModel.class, content);
		assertEquals(1, afterUpdate.getPages().size());
	}

	@Test
	public void testGetRunScenarioModelById() throws JAXBException {
		doSaveAScript(getUserForTest());
		assertNotNull(this.getScriptService().getRunSceniroModelByScriptId(
				getUploadScriptId(getUserForTest())));

	}

	@After
	public void cleanUp() {
		try {
			User user = this.getUserRepository().getUser("test1");
			int uploadScriptId = getUploadScriptId(user);
			assertTrue(this.getScriptService().deleteScript(uploadScriptId,
					user.getId()));
			this.getUserRepository().detach("test1");
		} catch (Exception e) {
		}
	}
}
