package org.bench4q.agent.test.plugin;

import static org.junit.Assert.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

import org.bench4q.agent.plugin.PluginManager;
import org.bench4q.agent.plugin.basic.csvprovider.CsvProvider;
import org.bench4q.agent.scenario.Scenario;
import org.bench4q.agent.scenario.engine.VUser;
import org.bench4q.agent.test.TestBase;
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.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_CsvProvider extends TestBase {

	private static final String CONTENT = "chentienan,1234"
			+ System.getProperty("line.separator") + "wangxiaoer,2345";
	@Autowired
	private PluginManager pluginManager;

	@Test
	public void test_InitialRightly_By_PluginManager() throws IOException {
		String fileName = "para_csv";
		final UUID testId = UUID.randomUUID();
		createFileAndWriteContent(testId, fileName, CONTENT);
		Map<String, String> parameters = buildInitParametersNotBigFile(fileName);
		Map<String, String> extraParameters = new HashMap<String, String>() {
			private static final long serialVersionUID = 1L;
			{
				put("testId", testId.toString());
			}
		};
		CsvProvider csvProvider = (CsvProvider) this.pluginManager
				.initializePlugin(
						this.pluginManager.getPlugins().get("CsvProvider"),
						parameters, extraParameters);
		csvProvider.close();
		assertNotNull(csvProvider);
		dropFiles(testId);
	}

	private Map<String, String> buildInitParametersNotBigFile(String fileName) {
		Map<String, String> parameters = new HashMap<String, String>();
		parameters.put("fileName", fileName);
		parameters.put("separator", ",");
		parameters.put("fieldNames", "userName, password");
		parameters.put("shared", "Notenable");
		parameters.put("loop", "enable");
		parameters.put("loadAtRunTime", "Notenable");
		parameters.put("commentPrefix", null);
		return parameters;
	}

	private List<ParameterModel> buildParameterModels(Map<String, String> params) {
		List<ParameterModel> result = new ArrayList<ParameterModel>();
		for (final Entry<String, String> entry : params.entrySet()) {
			result.add(new ParameterModel() {
				{
					setKey(entry.getKey());
					setValue(entry.getValue());
				}
			});
		}
		return result;
	}

	@Test
	public void test_InitialRightly_By_VUser() throws IOException {
		final String fileName = "param_csv";
		UUID testId = UUID.randomUUID();
		createFileAndWriteContent(testId, fileName, CONTENT);
		RunScenarioModel runScenarioModel = buildRunScenarioModel(fileName);
		Scenario scenario = Scenario
				.scenarioBuilderWithCompile(runScenarioModel);
		VUser vUser = createVUser(scenario, testId);
		try {
			HashMap<String, Object> plugins = new HashMap<String, Object>();
			TestHelper.invokePrivate(vUser, "preparePlugins", new Class<?>[] {
					Scenario.class, Map.class }, new Object[] { scenario,
					plugins });
			assertTrue(plugins.containsKey("csvProvider0"));
			dropFiles(testId);
		} catch (Exception e) {
			e.printStackTrace();
			fail();
		}
	}

	private RunScenarioModel buildRunScenarioModel(final String fileName) {
		RunScenarioModel runScenarioModel = new RunScenarioModel();
		runScenarioModel.getUsePlugins().add(new UsePluginModel() {
			{
				setId("csvProvider0");
				setName("CsvProvider");
				setParameters(buildParameterModels(buildInitParametersNotBigFile(fileName)));
			}
		});
		return runScenarioModel;
	}

	@Test
	public void test_DoGet() throws Exception {
		String fileName = "para_csv";
		UUID testId = UUID.randomUUID();
		createFileAndWriteContent(testId, fileName, CONTENT);
		Scenario scenario = Scenario
				.scenarioBuilderWithCompile(buildRunScenarioModel(fileName));
		VUser vUser = createVUser(scenario, testId);
		HashMap<String, Object> plugins = new HashMap<String, Object>();
		TestHelper
				.invokePrivate(vUser, "preparePlugins", new Class<?>[] {
						Scenario.class, Map.class }, new Object[] { scenario,
						plugins });
		CsvProvider csvProvider = (CsvProvider) plugins.get("csvProvider0");
		csvProvider.doNext();
		assertNotNull(csvProvider.getValue("userName"));
		assertEquals("chentienan", csvProvider.getValue("userName"));
		dropFiles(testId);
	}
}
