package org.bench4q.web.masterMessager;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBException;
import org.bench4q.share.communication.HttpRequester.HttpResponse;
import org.bench4q.share.helper.MarshalHelper;
import org.bench4q.share.models.master.TestPlanDBModel;
import org.bench4q.share.models.master.TestPlanResponseModel;
import org.bench4q.share.models.master.TestPlanResultModel;
import org.bench4q.share.models.master.TestPlanScriptBriefResultModel;
import org.bench4q.share.models.master.statistics.ScriptBehaviorsBriefModel;
import org.bench4q.share.models.master.statistics.ScriptBriefResultModel;
import org.bench4q.share.models.master.statistics.ScriptPagesBriefModel;
import org.springframework.stereotype.Component;

@Component
public class TestPlanMessager extends MasterMessager {

	public TestPlanMessager() {
		super(MasterAddressManamger.getMasterAddress() + "/testPlan");
	}

	public HttpResponse loadReport(String accessToken, String testPlanId) {
		String url = this.getBaseUrl() + "/getTestPlanReport";
		HttpResponse httpResponse = null;
		try {
			Map<String, String> params = new HashMap<String, String>();
			params.put("testPlanRunID", testPlanId);
			httpResponse = this.getHttpRequester().sendGet(url, params,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				return null;
			}
			return httpResponse;
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return null;
		}

	}

	public TestPlanResultModel runTestPlan(String accessToken,
			String testPlanXmlContent) {

		String url = this.getBaseUrl() + "/run";
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendPostXml(url,
					testPlanXmlContent, makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse))
				return null;
			return extractTestPlanResultModel(httpResponse);
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return null;
		}

	}

	public TestPlanResultModel getRunningTestInfo(String accessToken,
			String testPlanId) {
		String url = this.getBaseUrl() + "/getRunningInfo";
		Map<String, String> params = new HashMap<String, String>();
		params.put("testPlanId", testPlanId);
		return this.getTestPlanResultModelByPost(url, params, accessToken);

	}

	public TestPlanScriptBriefResultModel getScriptBriefResult(
			String accessToken, String testPlanId, String scriptId,
			String duationBegin) {
		String url = this.getBaseUrl() + "/scriptBrief" + "/" + testPlanId
				+ "/" + scriptId + "/" + duationBegin;
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendGet(url, null,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				handleInvalidatedResponse(url);
				return null;
			}

			return (TestPlanScriptBriefResultModel) MarshalHelper.unmarshal(
					TestPlanScriptBriefResultModel.class,
					httpResponse.getContent());
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return null;
		}
	}

	public ScriptBehaviorsBriefModel getScriptBehaviorsBriefResult(
			String accessToken, String testPlanId, String scriptId) {
		String url = this.getBaseUrl() + "/getBehaviorsBrief" + "/"
				+ testPlanId + "/" + scriptId;
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendGet(url, null,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse))
				return null;
			return (ScriptBehaviorsBriefModel) MarshalHelper.unmarshal(
					ScriptBehaviorsBriefModel.class, httpResponse.getContent());
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return null;
		}

	}

	public TestPlanDBModel queryTestPlanById(String accessToken,
			String testPlanRunId) {
		String url = this.getBaseUrl() + "/queryTestPlan" + "/" + testPlanRunId;
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendGet(url, null,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				handleInvalidatedResponse(url);
				return null;
			}
			return (TestPlanDBModel) MarshalHelper.unmarshal(
					TestPlanDBModel.class, httpResponse.getContent());
		} catch (Exception e) {
			handleException(httpResponse, e);
			return null;
		}

	}

	public TestPlanResponseModel deleteTestPlan(String accessToken,
			String testPlanId) {
		String url = this.getBaseUrl() + "/removeTestPlanFromPool";
		Map<String, String> params = new HashMap<String, String>();
		params.put("testPlanId", testPlanId);
		return getTestPlanResponseModel(url, params, accessToken);

	}

	public TestPlanResponseModel loadTestPlans(String accessToken) {
		String url = this.getBaseUrl() + "/loadTestPlans";
		return getTestPlanResponseModel(url, null, accessToken);
	}

	public HttpResponse getTestPlanReport(String accessToken,
			String testPlanRunId) {
		String url = this.getBaseUrl() + "/getTestPlanReport";
		Map<String, String> params = new HashMap<String, String>();
		params.put("testPlanRunID", testPlanRunId);
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendPost(url, params,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse))
				return null;
			return httpResponse;

		} catch (IOException e) {
			this.handleException(httpResponse, e);
			return null;
		}
	}

	private TestPlanResponseModel getTestPlanResponseModel(String url,
			Map<String, String> params, String accessToken) {
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendPost(url, params,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				handleInvalidatedResponse(url);
				return null;
			}

			return extractTestPlanResponseModel(httpResponse);

		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return createFailTestPlanResponseModel();
		}
	}

	private TestPlanResponseModel createFailTestPlanResponseModel() {
		TestPlanResponseModel testPlanResponseModel = new TestPlanResponseModel();
		testPlanResponseModel.setSuccess(false);
		testPlanResponseModel.setFailCause("");
		return testPlanResponseModel;
	}

	private TestPlanResultModel getTestPlanResultModelByPost(String url,
			Map<String, String> params, String accessToken) {
		HttpResponse httpResponse = null;
		try {

			httpResponse = this.getHttpRequester().sendPost(url, params,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse))
				return null;
			return extractTestPlanResultModel(httpResponse);
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return null;
		}
	}

	private TestPlanResponseModel extractTestPlanResponseModel(
			HttpResponse httpResponse) throws JAXBException,
			UnsupportedEncodingException {
		return (TestPlanResponseModel) MarshalHelper.unmarshal(
				TestPlanResponseModel.class, httpResponse.getContent());
	}

	private TestPlanResultModel extractTestPlanResultModel(
			HttpResponse httpResponse) throws JAXBException,
			UnsupportedEncodingException {
		return (TestPlanResultModel) MarshalHelper.unmarshal(
				TestPlanResultModel.class, httpResponse.getContent());

	}

	public ScriptBriefResultModel getLatestScriptBriefResult(
			String accessToken, String testPlanId, String scriptId) {
		String url = this.baseUrl + "/scriptBrief" + "/" + testPlanId + "/"
				+ scriptId + "/latestResult";
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendGet(url, null,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				handleInvalidatedResponse(url);
				return null;
			}
			return (ScriptBriefResultModel) MarshalHelper.tryUnmarshal(
					ScriptBriefResultModel.class, httpResponse.getContent());

		} catch (Exception e) {
			handleException(httpResponse, e);
			return null;
		}
	}

	public ScriptPagesBriefModel getScriptPageBriefModel(String accessToken,
			String testPlanId, String scriptId) {
		String url = this.baseUrl + "/pagesBrief" + "/" + testPlanId + "/"
				+ scriptId;
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().sendGet(url, null,
					makeAccessTockenMap(accessToken));
			if (!validateHttpResponse(httpResponse)) {
				handleInvalidatedResponse(url);
				return null;
			}
			return (ScriptPagesBriefModel) MarshalHelper.unmarshal(
					ScriptPagesBriefModel.class, httpResponse.getContent());

		} catch (Exception e) {
			handleException(httpResponse, e);
			return null;
		}
	}

	public TestPlanResponseModel stopTestPlan(String accessToken,
			String testPlanRunId) {
		String url = this.baseUrl + "/stop" + "/" + testPlanRunId;
		return getTestPlanResponseModel(url, null, accessToken);
	}
	
	public TestPlanResponseModel loadFilterTypeList(String accessToken) {
		String url = this.getBaseUrl() + "/loadFilterTypeList";
		return getTestPlanResponseModel(url, null, accessToken);
	}
}