package org.bench4q.web.api;

import java.util.HashMap;
import java.util.Map;

import org.bench4q.share.enums.master.AgentStatus;
import org.bench4q.share.helper.MarshalHelper;
import org.bench4q.share.models.master.AgentModel;
import org.bench4q.share.models.master.AgentResponseModel;
import org.bench4q.web.masterMessager.AgentManagerMessager;
import org.bench4q.web.validation.AgentValidate;
import org.bench4q.web.validation.ValidateResponseModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@SessionAttributes({ "accessToken" })
public class AgentController extends BaseController {
	public final int IN_IDLE = 1;

	private AgentValidate agentValidate;

	private AgentManagerMessager agentManagerMessenger;

	private AgentValidate getAgentValidate() {
		return agentValidate;
	}

	@Autowired
	private void setAgentValidate(AgentValidate agentValidate) {
		this.agentValidate = agentValidate;
	}

	private AgentManagerMessager getAgentManagerMessenger() {
		return agentManagerMessenger;
	}

	@Autowired
	private void setAgentManagerMessenger(
			AgentManagerMessager agentManagerMessenger) {
		this.agentManagerMessenger = agentManagerMessenger;
	}

	@RequestMapping("addAgent")
	@ResponseBody
	public Map<String, Object> addAgent(
			@ModelAttribute("accessToken") String accessToken,
			@RequestParam String hostName, @RequestParam String port,
			@RequestParam String maxLoad) {
		Map<String, Object> map = new HashMap<String, Object>();
		ValidateResponseModel validateResponseModel = this.getAgentValidate()
				.validateAddedAgent(hostName, maxLoad, port);
		if (!validateResponseModel.isSuccess())
			return fail(map, validateResponseModel.getMessage());
		String agentModelContnet = MarshalHelper.tryMarshal(buildAgentModel(
				hostName, port, maxLoad));
		if (agentModelContnet == null) {
			return fail(map, "agent input info is error");
		}

		AgentResponseModel agentResponseModel = this.getAgentManagerMessenger()
				.addAgent(accessToken, agentModelContnet);
		return processAgentResposeModel(agentResponseModel, map);

	}

	@RequestMapping("/deleteAgent")
	@ResponseBody
	public Map<String, Object> deleteAgent(
			@ModelAttribute("accessToken") String accessToken,
			@RequestParam String agentId, @RequestParam String hostName) {
		Map<String, Object> map = new HashMap<String, Object>();
		ValidateResponseModel validateResponseModel = this.getAgentValidate()
				.validateDeleteAgent(hostName, agentId);
		if (!validateResponseModel.isSuccess()) {
			return fail(map, validateResponseModel.getMessage());
		}
		AgentResponseModel agentResponseModel = this.getAgentManagerMessenger()
				.deleteAgent(accessToken, agentId, hostName);
		return processAgentResposeModel(agentResponseModel, map);
	}

	@RequestMapping("/loadAgents")
	@ResponseBody
	public Map<String, Object> loadAgents(
			@ModelAttribute("accessToken") String accessToken) {
		Map<String, Object> map = new HashMap<String, Object>();
		AgentResponseModel agentResponseModel = this.getAgentManagerMessenger()
				.loadAgents(accessToken);
		if (agentResponseModel.isSuccess()) {
			map = success(map);
			map.put("agents", agentResponseModel.getAgents());
		} else {
			map = fail(map, agentResponseModel.getFailCauseString());
		}
		return map;
	}

	private Map<String, Object> processAgentResposeModel(
			AgentResponseModel agentResponseModel, Map<String, Object> map) {

		if (agentResponseModel.isSuccess()) {
			return success(map);
		}

		return fail(map, agentResponseModel.getFailCauseString());
	}

	private AgentModel buildAgentModel(String hostName, String port,
			String maxLoad) {
		AgentModel agent = new AgentModel();
		agent.setHostName(hostName);
		agent.setPort(Integer.parseInt(port));
		agent.setCurrentEnumStatus(AgentStatus.InIdle);
		agent.setMaxLoad(Integer.parseInt(maxLoad));
		agent.setRemainLoad(Integer.parseInt(maxLoad));
		return agent;
	}

}
