package org.bench4q.agent.test.datastatistics;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.bench4q.agent.datacollector.DataCollector;
import org.bench4q.agent.datacollector.impl.ScenarioResultCollector;
import org.bench4q.agent.scenario.engine.BehaviorResult;
import org.bench4q.agent.scenario.engine.PageResult;
import org.bench4q.agent.storage.StorageHelper;
import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ScenarioStatisticsTest {
	private DataCollector dataStatistics;

	protected DataCollector getDataStatistics() {
		return dataStatistics;
	}

	private void setDataStatistics(DataCollector dataStatistics) {
		this.dataStatistics = dataStatistics;
	}

	public ScenarioStatisticsTest() {
		init();
	}

	public void init() {
		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"classpath*:/org/bench4q/agent/config/application-context.xml");
		ScenarioResultCollector agentResultDataCollector = new ScenarioResultCollector(
				UUID.randomUUID());
		agentResultDataCollector.setStorageHelper((StorageHelper) context
				.getBean(StorageHelper.class));
		this.setDataStatistics(agentResultDataCollector);
	}

	@Test
	public void addZeroBriefTest() {
		for (BehaviorResult behaviorResult : makeBehaviorListWhoseBehaviorIdIsOne(0)) {
			this.getDataStatistics().add(behaviorResult);
		}
		AgentBriefStatusModel model = (AgentBriefStatusModel) this
				.getDataStatistics().getScenarioBriefStatistics();
		AgentBriefStatusModel modelExpect = makeAllZeroModel();
		modelExpect.setTimeFrame(model.getTimeFrame());
		assertTrue(model.equals(modelExpect));
	}

	@Test
	public void addOneBriefTest() throws InterruptedException {
		for (BehaviorResult behaviorResult : makeBehaviorListWhoseBehaviorIdIsOne(1)) {
			this.getDataStatistics().add(behaviorResult);
		}

		Thread.sleep(100);
		AgentBriefStatusModel model = (AgentBriefStatusModel) this
				.getDataStatistics().getScenarioBriefStatistics();
		AgentBriefStatusModel modelExpect = new AgentBriefStatusModel();
		modelExpect.setTimeFrame(model.getTimeFrame());
		makeUpStatusModelForOneBehavior(modelExpect);
		assertTrue(model.equals(modelExpect));
	}

	@Test
	public void addTwoBriefTest() throws InterruptedException {
		for (BehaviorResult behaviorResult : makeBehaviorListWhoseBehaviorIdIsOne(2)) {
			this.getDataStatistics().add(behaviorResult);
		}
		Thread.sleep(100);
		AgentBriefStatusModel model = (AgentBriefStatusModel) this
				.getDataStatistics().getScenarioBriefStatistics();
		AgentBriefStatusModel modelExpect = makeUpStatusModelForTwoBehavior(model
				.getTimeFrame());
		assertTrue(model.equals(modelExpect));
	}

	public static AgentBriefStatusModel makeUpStatusModelForTwoBehavior(
			long timeFrame) {
		AgentBriefStatusModel model = new AgentBriefStatusModel();
		model.setTimeFrame(timeFrame);
		model.setSuccessThroughputThisTime(1 * 1000 / timeFrame);
		model.setFailCountFromBegin(1);
		model.setFailThroughputThisTime(1 * 1000 / timeFrame);
		model.setMaxResponseTime(200);
		model.setMinResponseTime(200);
		model.setSuccessCountFromBegin(1);
		model.setSuccessCountThisTime(1);
		model.setFailCountThisTime(1);
		model.setTotalResponseTimeThisTime(200);
		model.setTotalSqureResponseTimeThisTime(40000);
		return model;
	}

	public static void makeUpStatusModelForOneBehavior(
			AgentBriefStatusModel model) {
		model.setSuccessThroughputThisTime(1 * 1000 / model.getTimeFrame());
		model.setFailCountFromBegin(0);
		model.setFailThroughputThisTime(0);
		model.setMaxResponseTime(200);
		model.setMinResponseTime(200);
		model.setSuccessCountFromBegin(1);
		model.setSuccessCountThisTime(1);
		model.setFailCountThisTime(0);
		model.setTotalResponseTimeThisTime(200);
		model.setTotalSqureResponseTimeThisTime(40000);
	}

	public static AgentBriefStatusModel makeAllZeroModel() {
		AgentBriefStatusModel model = new AgentBriefStatusModel();
		model.setSuccessThroughputThisTime(0);
		model.setFailCountFromBegin(0);
		model.setFailThroughputThisTime(0);
		model.setMaxResponseTime(0);
		model.setMinResponseTime(0);
		model.setTimeFrame(0);
		model.setSuccessCountFromBegin(0);
		model.setTotalResponseTimeThisTime(0);
		model.setSuccessCountThisTime(0);
		model.setFailCountThisTime(0);
		model.setTotalSqureResponseTimeThisTime(0);
		return model;
	}

	public static PageResult makePageResultWithBehaviorResult(int count) {
		List<BehaviorResult> behaviorResults = makeBehaviorListWhoseBehaviorIdIsOne(count);
		return PageResult.buildPageResult(2, behaviorResults);
	}

	public static List<BehaviorResult> makeBehaviorListWhoseBehaviorIdIsOne(
			int count) {
		List<BehaviorResult> behaviorResults = new ArrayList<BehaviorResult>();
		for (int i = 0; i < count; i++) {
			int statusCode = i % 2 == 0 ? 200 : 400;
			behaviorResults.add(buildBehaviorResult(200 + 10 * i, i % 2 == 0,
					statusCode, 1, 200 + 10 * i));
		}
		return behaviorResults;
	}

	public static BehaviorResult buildBehaviorResult(long responseTime,
			boolean success, int statusCode, int behaviorId, long startDateTime) {
		Date date = new Date(startDateTime);
		BehaviorResult result = new BehaviorResult();
		result.setBehaviorName("");
		result.setEndDate(new Date(date.getTime() + responseTime));
		result.setPluginId("Get");
		result.setPluginName("get");
		result.setResponseTime(responseTime);
		result.setStartDate(date);
		result.setSuccessCount(success ? 1 : 0);
		result.setFailCount(success ? 0 : 1);
		result.setShouldBeCountResponseTime(true);

		result.setBehaviorId(behaviorId);
		if (success) {
			result.setContentLength(20);
			result.setContentType("image");
		} else {
			result.setContentLength(0);
			result.setContentType("");
		}
		result.setStatusCode(statusCode);
		return result;
	}

}
