package org.bench4q.master.domain.valueobject.datastatistics;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bench4q.share.models.agent.BehaviorBriefModel;
import org.bench4q.share.models.agent.BehaviorStatusCodeResultModel;
import org.bench4q.share.models.agent.statistics.DataStatisticsModel;
import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel;
import org.bench4q.share.models.master.statistics.ScriptBehaviorsBriefModel;

public class BehaviorsBriefStatistics extends ScriptStatistics {
	private Map<Integer, Map<Integer, BehaviorStatusCodeResultModel>> map;
	private Map<Integer, String> idUrlMap;

	private Map<Integer, Map<Integer, BehaviorStatusCodeResultModel>> getMap() {
		return map;
	}

	private void setMap(
			Map<Integer, Map<Integer, BehaviorStatusCodeResultModel>> map) {
		this.map = map;
	}

	public Map<Integer, String> getIdUrlMap() {
		return idUrlMap;
	}

	public void setIdUrlMap(Map<Integer, String> idUrlMap) {
		this.idUrlMap = idUrlMap;
	}

	public BehaviorsBriefStatistics() {
		this.setMap(new HashMap<Integer, Map<Integer, BehaviorStatusCodeResultModel>>());
		this.setIdUrlMap(new HashMap<Integer, String>());
	}

	public ScriptBehaviorsBriefModel getStatistics() {
		ScriptBehaviorsBriefModel result = new ScriptBehaviorsBriefModel();
		AgentBehaviorsBriefModel agentBehaviorsBriefModel = new AgentBehaviorsBriefModel();
		List<BehaviorBriefModel> list = new ArrayList<BehaviorBriefModel>();
		for (int behaviorId : this.getMap().keySet()) {
			BehaviorBriefModel behaviorBriefModel = new BehaviorBriefModel();
			behaviorBriefModel.setBehaviorId(behaviorId);
			behaviorBriefModel.setBehaviorUrl(this.getIdUrlMap()
					.get(behaviorId));
			List<BehaviorStatusCodeResultModel> statusList = new ArrayList<BehaviorStatusCodeResultModel>();
			for (int statusCode : this.getMap().get(behaviorId).keySet()) {
				statusList.add(getCopy(behaviorId, statusCode));
			}
			behaviorBriefModel.setDetailStatusCodeResultModels(statusList);
			this.setBehaviorCount(behaviorBriefModel);
			list.add(behaviorBriefModel);
		}
		agentBehaviorsBriefModel.setBehaviorBriefModels(list);
		result.setBehaviorBriefModels(agentBehaviorsBriefModel
				.getBehaviorBriefModels());
		makeUpResultModelWithSamplingTime(result);
		return result;
	}

	private void setBehaviorCount(BehaviorBriefModel behaviorBriefModel) {
		long totalCount = 0, successfulCount = 0;
		if (behaviorBriefModel.getDetailStatusCodeResultModels() == null) {
			return;
		}
		for (BehaviorStatusCodeResultModel behaviorStatusCodeResultModel : behaviorBriefModel
				.getDetailStatusCodeResultModels()) {
			totalCount += behaviorStatusCodeResultModel.getCount();
			if (behaviorStatusCodeResultModel.getStatusCode() == 200) {
				successfulCount += behaviorStatusCodeResultModel.getCount();
			}
		}
		behaviorBriefModel.setTotalCount(totalCount);
		behaviorBriefModel.setSuccessfulCount(successfulCount);
	}

	private BehaviorStatusCodeResultModel getCopy(int behaviorId, int statusCode) {
		BehaviorStatusCodeResultModel statusInMap = this.getMap()
				.get(behaviorId).get(statusCode);
		BehaviorStatusCodeResultModel ret = new BehaviorStatusCodeResultModel();
		ret.setStatusCode(statusCode);
		ret.setContentLength(statusInMap.getContentLength());
		ret.setContentType(statusInMap.getContentType());
		ret.setCount(statusInMap.getCount());
		ret.setMaxResponseTime(statusInMap.getMaxResponseTime());
		ret.setMinResponseTime(statusInMap.getMinResponseTime());
		ret.setTotalResponseTimeThisTime(statusInMap
				.getTotalResponseTimeThisTime());
		return ret;
	}

	public void add(DataStatisticsModel dataUnit) {
		if (!(dataUnit instanceof AgentBehaviorsBriefModel)) {
			return;
		}
		AgentBehaviorsBriefModel input = (AgentBehaviorsBriefModel) dataUnit;
		for (BehaviorBriefModel behaviorBriefModel : input
				.getBehaviorBriefModels()) {
			guardAllMapsKeyExists(behaviorBriefModel);
			Map<Integer, BehaviorStatusCodeResultModel> behaviorStatusMap = this
					.getMap().get(behaviorBriefModel.getBehaviorId());
			for (BehaviorStatusCodeResultModel newOne : behaviorBriefModel
					.getDetailStatusCodeResultModels()) {
				if (!behaviorStatusMap.containsKey(newOne.getStatusCode())) {
					behaviorStatusMap.put(newOne.getStatusCode(), newOne);
					continue;
				}
				BehaviorStatusCodeResultModel origin = behaviorStatusMap
						.get(newOne.getStatusCode());
				origin.setContentLength(origin.getContentLength()
						+ newOne.getContentLength());
				origin.setCount(origin.getCount() + newOne.getCount());
				origin.setTotalResponseTimeThisTime(origin
						.getTotalResponseTimeThisTime()
						+ newOne.getTotalResponseTimeThisTime());
				if (newOne.getMaxResponseTime() > origin.getMaxResponseTime()) {
					origin.setMaxResponseTime(newOne.getMaxResponseTime());
				}
				if (newOne.getMinResponseTime() < origin.getMinResponseTime()) {
					origin.setMinResponseTime(newOne.getMinResponseTime());
				}
			}
		}
	}

	private synchronized void guardAllMapsKeyExists(
			BehaviorBriefModel behaviorBriefModel) {
		if (!this.getMap().containsKey(behaviorBriefModel.getBehaviorId())) {
			this.getMap().put(behaviorBriefModel.getBehaviorId(),
					new HashMap<Integer, BehaviorStatusCodeResultModel>());
		}
		if (!this.getIdUrlMap().containsKey(behaviorBriefModel.getBehaviorId())) {
			this.getIdUrlMap().put(behaviorBriefModel.getBehaviorId(),
					behaviorBriefModel.getBehaviorUrl());
		}
	}
}
