package org.bench4q.web.api;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.bench4q.share.models.master.plugin.BehaviorInfoModel;
import org.bench4q.share.models.master.plugin.PluginResponseModel;
import org.bench4q.web.masterMessager.PluginMessager;
import org.bench4q.web.validation.PluginValidate;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

@Controller
@SessionAttributes({ "accessToken" })
public class PluginController extends BaseController {

	private PluginMessager pluginMessager;

	private PluginValidate pluginValidation;

	public PluginMessager getPluginMessager() {
		return pluginMessager;
	}

	@Autowired
	public void setPluginMessager(PluginMessager pluginMessager) {
		this.pluginMessager = pluginMessager;
	}

	public PluginValidate getPluginValidation() {
		return pluginValidation;
	}

	@Autowired
	public void setPluginValidation(PluginValidate pluginValidation) {
		this.pluginValidation = pluginValidation;
	}

	@RequestMapping("loadPluginName")
	public @ResponseBody
	Map<String, Object> loadPluginName(HttpServletRequest request,
			@ModelAttribute("accessToken") String accessToken) {
		Map<String, Object> map = new HashMap<String, Object>();
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.loadPluginNameList(accessToken);
		if (pluginResponseModel.isSuccess()) {
			map = success(map);
			map.put("pluginNames", pluginResponseModel.getPluginList());
			return map;

		} else {
			map = fail(map, pluginResponseModel.getFailMessage());
			return map;

		}

	}

	@RequestMapping("loadPluginUIList")
	public @ResponseBody
	Map<String, Object> loadPluginUIInfo(HttpServletRequest request,
			@ModelAttribute("accessToken") String accessToken) {
		Map<String, Object> map = new HashMap<String, Object>();
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.loadPluginUIModels(accessToken);
		if (pluginResponseModel.isSuccess()) {
			map = success(map);
			map.put("pluginUIs", pluginResponseModel.getPluginUIModels());
		} else {
			map = fail(map, pluginResponseModel.getFailMessage());
		}

		return map;
	}

	@RequestMapping("loadBehaviorList")
	public @ResponseBody
	Map<String, Object> loadBehaviorList(HttpServletRequest request,
			@ModelAttribute("accessToken") String accessToken,
			@RequestParam String pluginName) {

		Map<String, Object> map = new HashMap<String, Object>();
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.loadBehaviors(accessToken, pluginName);
		if (pluginResponseModel.isSuccess()) {
			map = success(map);
			map.put("behaviors", pluginResponseModel.getBehaviorInfoModels());
		} else {
			map = fail(map, pluginResponseModel.getFailMessage());
		}
		return map;
	}

	@RequestMapping(value = "uploadPluginFile", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> uploadPluginFile(
			@ModelAttribute("accessToken") String accessToken,
			@RequestParam CommonsMultipartFile pluginFile) {
		Map<String, Object> map = new HashMap<String, Object>();
		ValidateResponseModel validateResponseModel = this
				.getPluginValidation().validatePluginUIFile(pluginFile);
		if (!validateResponseModel.isSuccess()) {
			return fail(map, validateResponseModel.getMessage());
		}

		PluginResponseModel pluginResponseModel;
		try {
			pluginResponseModel = this.getPluginMessager().addPlugin(
					accessToken, new String(pluginFile.getBytes(), "utf-8"));
			return processPluginResponseModel(map, pluginResponseModel);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			return fail(map, "");
		}

	}

	@RequestMapping("deletePluginByPluginName")
	public @ResponseBody
	Map<String, Object> deletePluginByPluginName(
			@ModelAttribute("accessToken") String accessToken,
			@RequestParam String pluginName) {
		Map<String, Object> map = new HashMap<String, Object>();
		ValidateResponseModel validateResponseModel = this
				.getPluginValidation().validatePluginName(pluginName);
		if (!validateResponseModel.isSuccess()) {
			return fail(map, validateResponseModel.getMessage());
		}
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.deletePlugin(accessToken, pluginName);
		return processPluginResponseModel(map, pluginResponseModel);
	}

	private Map<String, Object> processPluginResponseModel(
			Map<String, Object> map, PluginResponseModel pluginResponseModel) {
		if (pluginResponseModel != null && pluginResponseModel.isSuccess()) {
			return success(map);
		} else {
			return fail(map, "");
		}

	}

	@RequestMapping("getPlugin/{pluginName}")
	@ResponseBody
	public Map<String, Object> getPlugin(
			@ModelAttribute("accessToken") String accessToken,
			@PathVariable String pluginName) {
		Map<String, Object> map = new HashMap<String, Object>();
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.getPluginInfoModel(accessToken, pluginName);
		if (pluginResponseModel.isSuccess()
				&& pluginResponseModel.getPluginInfoModel() != null) {
			map = success(map);
			map.put("plugin", pluginResponseModel.getPluginInfoModel());
			return map;
		} else {
			return fail(map, pluginResponseModel.getFailMessage());
		}
	}

	@RequestMapping("getPluginMethod/{pluginName}/{methodName}")
	@ResponseBody
	public Map<String, Object> getMethod(
			@ModelAttribute("accessToken") String accessToken,
			@PathVariable String pluginName, @PathVariable String methodName) {
		Map<String, Object> map = new HashMap<String, Object>();
		PluginResponseModel pluginResponseModel = this.getPluginMessager()
				.loadBehaviors(accessToken, pluginName);
		for (BehaviorInfoModel behaviorInforModel : pluginResponseModel
				.getBehaviorInfoModels()) {
			if (behaviorInforModel.getName().equals(methodName)) {
				map.put("method", behaviorInforModel);
				success(map);
				return map;
			}
		}

		return fail(map, "");
	}
}
