package org.bench4q.web.masterMessager;

import java.util.HashMap;
import java.util.LinkedHashMap;
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.OperateScriptServerResponseModel;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

@Component
public class ScriptMessager extends MasterMessager {
	public ScriptMessager() {
		super(MasterAddressManamger.getMasterAddress() + "/script");
	}

	public OperateScriptServerResponseModel startScriptRecordServer(
			String accessToken) {
		String url = this.getBaseUrl() + "/startScriptRecordServer";
		return this.getOperateScriptServerResponseModelByPost(url, null,
				accessToken);

	}

	public OperateScriptServerResponseModel startRecording(
			String accessToken, String port, String fileNameUUID) {
		String url = this.getBaseUrl() + "/startScriptRecording";
		Map<String, String> params = new HashMap<String, String>();
		params.put("port", port);
		params.put("fileNameUUID", fileNameUUID);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);
	}
	
	public OperateScriptServerResponseModel stopScriptRecordServer(
			String accessToken, String port, String fileNameUUID) {
		String url = this.getBaseUrl() + "/stopScriptRecordServer";
		Map<String, String> params = new HashMap<String, String>();
		params.put("port", port);
		params.put("fileNameUUID", fileNameUUID);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);
	}

	public OperateScriptServerResponseModel stopScriptRecording(
			String accessToken, String port, String fileNameUUID) {
		String url = this.getBaseUrl() + "/stopScriptRecording";
		Map<String, String> params = new HashMap<String, String>();
		params.put("port", port);
		params.put("fileNameUUID", fileNameUUID);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);
	}
	
	public OperateScriptServerResponseModel saveScriptRecorded(
			String accessToken, String scriptName, String port,
			String fileNameUUID) {

		String url = this.getBaseUrl() + "/saveScriptToDB";
		Map<String, String> params = new HashMap<String, String>();
		params.put("scriptName", scriptName);
		params.put("port", port);
		params.put("fileNameUUID", fileNameUUID);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);

	}

	public OperateScriptServerResponseModel uploadScriptFile(
			String accessToken, String scriptName, String scenarioModel) {
		String url = this.getBaseUrl() + "/uploadScript" + "/" + scriptName;
		Map<String, String> stringPart = new HashMap<String, String>();
		stringPart.put("scenarioModel", scenarioModel);
		HttpResponse httpResponse = null;
		try {
			httpResponse = this.getHttpRequester().postFilesMulti(
					makeAccessTockenMap(accessToken), url, "paramFiles[]",
					null, stringPart);
			System.out.println(httpResponse.getContent());
			if (!validateHttpResponse(httpResponse))
				return null;
			return (OperateScriptServerResponseModel) MarshalHelper.unmarshal(
					OperateScriptServerResponseModel.class,
					httpResponse.getContent());

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

	}

	public OperateScriptServerResponseModel uploadScript(String accessToken,
			String scriptName, String scenarioModel, MultipartFile[] paramFiles) {
		String url = this.getBaseUrl() + "/uploadScript" + "/" + scriptName;
		HttpResponse httpResponse = null;

		try {
			Map<String, String> stringParts = new LinkedHashMap<String, String>();
			stringParts.put("scenarioModel", scenarioModel);
			httpResponse = this.getHttpRequester().postFilesMulti(
					makeAccessTockenMap(accessToken), url, "paramFiles[]",
					paramFiles, stringParts);
			if (!validateHttpResponse(httpResponse))
				return null;
			return (OperateScriptServerResponseModel) MarshalHelper.unmarshal(
					OperateScriptServerResponseModel.class,
					httpResponse.getContent());

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

	}

	public OperateScriptServerResponseModel deleteScript(String accessToken,
			String scriptId) {
		String url = this.getBaseUrl() + "/deleteScript";
		Map<String, String> params = new HashMap<String, String>();
		params.put("scriptId", scriptId);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);
	}

	public OperateScriptServerResponseModel updateScript(String accessToken,
			String scriptId,String scriptContent, String scriptName) {
		String url = this.getBaseUrl() + "/updateScript" + "/" + scriptId;
		Map<String, String> params = new HashMap<String, String>();
		params.put("content", scriptContent);
		params.put("scriptName", scriptName);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);

	}

//	public OperateScriptServerResponseModel updateScript(String accessToken,
//			String scriptId, String scenarioModel,String scriptName, MultipartFile[] paramFiles) {
//		String url = this.getBaseUrl() + "/updateScript" + "/" + scriptId;
//		List<String> stringPart = new LinkedList<String>();
//		stringPart.add(scenarioModel);
//		stringPart.add(scriptName);
//		HttpResponse httpResponse = null;
//
//		try {
//			httpResponse = this.getHttpRequester().postFilesMulti(
//					makeAccessTockenMap(accessToken), url, "paramFiles[]",
//					paramFiles, "paramContents[]", stringPart);
//			if (!validateHttpResponse(httpResponse))
//				return null;
//			return (OperateScriptServerResponseModel) MarshalHelper.unmarshal(
//					OperateScriptServerResponseModel.class,
//					httpResponse.getContent());
//
//		} catch (Exception e) {
//			this.handleException(httpResponse, e);
//			return createFailOperateScriptServerResponseModel();
//		}
//
//	}
	
	public OperateScriptServerResponseModel loadScripts(String accessToken) {
		String url = this.getBaseUrl() + "/loadScriptList";
		return this.getOperateScriptServerResponseModelByPost(url, null,
				accessToken);
	}

	public OperateScriptServerResponseModel queryScriptById(String accessToken,
			String scriptId) {
		String url = this.getBaseUrl() + "/queryScriptById";
		Map<String, String> params = new HashMap<String, String>();
		params.put("scriptId", scriptId);
		OperateScriptServerResponseModel operateScriptServerResponseModel = this
				.getOperateScriptServerResponseModelByPost(url, params,
						accessToken);
		if (!operateScriptServerResponseModel.isSuccess()
				|| operateScriptServerResponseModel.getScriptModels().size() != 1) {
			operateScriptServerResponseModel.setSuccess(false);
			operateScriptServerResponseModel
					.setFailCauseString("error get script by id:" + scriptId);

		}
		return operateScriptServerResponseModel;
	}

	public OperateScriptServerResponseModel queryScriptByName(
			String accessToken, String scriptName) {
		String url = this.getBaseUrl() + "/queryScriptByName";
		Map<String, String> params = new HashMap<String, String>();
		params.put("name", scriptName);
		return this.getOperateScriptServerResponseModelByPost(url, params,
				accessToken);
	}


	
	private OperateScriptServerResponseModel getOperateScriptServerResponseModelByPost(
			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 createFailOperateScriptServerResponseModel();
			}
			return extractOperateScriptServerResponseModel(httpResponse);
		} catch (Exception e) {
			this.handleException(httpResponse, e);
			return createFailOperateScriptServerResponseModel();
		}
	}

	private OperateScriptServerResponseModel createFailOperateScriptServerResponseModel() {
		OperateScriptServerResponseModel operateScriptServerResponseModel = new OperateScriptServerResponseModel();
		operateScriptServerResponseModel.setSuccess(false);
		operateScriptServerResponseModel.setFailCauseString("");
		return operateScriptServerResponseModel;
	}

	private OperateScriptServerResponseModel extractOperateScriptServerResponseModel(
			HttpResponse httpResponse) throws JAXBException {
		return (OperateScriptServerResponseModel) MarshalHelper.unmarshal(
				OperateScriptServerResponseModel.class,
				httpResponse.getContent());
	}
}
