package com.mason.server.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.google.appengine.api.datastore.KeyFactory;
import com.mason.server.model.Log;
import com.mason.server.model.Project;
import com.mason.server.model.UmlModel;
import com.mason.server.dao.jdo.LogDAO;
import com.mason.server.dao.jdo.ProjectDAO;
import com.mason.server.dao.jdo.UmlModelDAO;
import com.mason.server.dao.jdo.UserDAO;
import com.mason.server.exception.ResourceNotFoundException;
 
@Controller
@RequestMapping("/{usernameSlug}/{projectSlug}/model/")
public class UmlModelController {

	private static UmlModelDAO modelDAO = new UmlModelDAO();
	private static ProjectDAO projectDAO = new ProjectDAO();
	private static UserDAO userDAO = new UserDAO();
	private static LogDAO logDAO = new LogDAO();

	@RequestMapping(value = "add", method = RequestMethod.GET)
	public String getUmlModelAddPage(@PathVariable String usernameSlug, @PathVariable String projectSlug, ModelMap model) {
		UmlModel umlModel = new UmlModel();
		Project p = projectDAO.getBySlug(projectSlug, userDAO.getByUsername(usernameSlug).getId());
		umlModel.setProjectId(p.getId());
		model.addAttribute("umlModel", umlModel);
		model.addAttribute("modelTypes", UmlModel.getModelTypes());
		return "model/umlModelAdd";
	}

	@RequestMapping(value = "add", method = RequestMethod.POST)
	public String add(@PathVariable String usernameSlug,
			@PathVariable String projectSlug, UmlModel umlModel,
			BindingResult result) {
		
		umlModel = processModel(umlModel);

		umlModel = modelDAO.add(umlModel);
		
		logDAO.add(new Log(umlModel.getId(), UmlModel.class.getSimpleName(),
				Log.Action.CREATE));

		return "redirect:/" + usernameSlug;
	}

	private UmlModel processModel(UmlModel umlModel) {
		umlModel.setProjectId(KeyFactory.stringToKey(umlModel.getProjectIdGenerated()).getId());

		umlModel.setDescription(umlModel.getDescription().trim());

		int i = 1;

		String description = umlModel.getDescription().toLowerCase()
				.replace(" ", "_");
		String slug = description;

		UmlModel um = modelDAO.getBySlug(slug, umlModel.getProjectId());

		while (um != null && um.getId() != umlModel.getId()) {
			slug = description + i;
			i++;
			um = modelDAO.getBySlug(slug, umlModel.getProjectId());
		}
		umlModel.setSlug(slug);
		return umlModel;
	}

	@RequestMapping(value = "{modelSlug}/update", method = RequestMethod.GET)
	public String getUmlModelUpdatePage(@PathVariable String usernameSlug,
			@PathVariable String projectSlug, @PathVariable String modelSlug,
			ModelMap model) {
		model.addAttribute("umlModel",
				getBySlugs(usernameSlug, projectSlug, modelSlug));
		model.addAttribute("modelTypes", UmlModel.getModelTypes());
		return "model/umlModelUpdate";
	}

	@RequestMapping(value = "{modelSlug}/update", method = RequestMethod.POST)
	public String update(@PathVariable String usernameSlug,
			@PathVariable String projectSlug, ModelMap model,
			UmlModel umlModel, BindingResult result) {

		umlModel = processModel(umlModel);


		UmlModelController.modelDAO.update(umlModel);
		logDAO.add(new Log(umlModel.getId(), UmlModel.class.getSimpleName(),
				Log.Action.UPDATE));

		return "redirect:/" + usernameSlug ;
	}

	@RequestMapping(value = "{modelSlug}/delete", method = RequestMethod.GET)
	public String getUmlModelDeletePage(@PathVariable String usernameSlug,
			@PathVariable String projectSlug, @PathVariable String modelSlug,
			HttpServletRequest request, ModelMap model) {
		model.addAttribute("umlModel",
				getBySlugs(usernameSlug, projectSlug, modelSlug));
		return "model/umlModelDelete";
	}

	@RequestMapping(value = "{modelSlug}/delete", method = RequestMethod.POST)
	public String delete(@PathVariable String usernameSlug,
			@PathVariable String projectSlug, @PathVariable String modelSlug,
			HttpServletRequest request, Model model) {
		UmlModel umlModel = getBySlugs(usernameSlug, projectSlug, modelSlug);
		modelDAO.delete(umlModel);
		logDAO.add(new Log(umlModel.getId(), UmlModel.class.getSimpleName(),
				Log.Action.DELETE));
		return "redirect:/" + usernameSlug ;
	}

	private UmlModel getBySlugs(String username, String projectSlug,
			String modelSlug) {
		UmlModel umlModel = modelDAO.getBySlug(
				modelSlug,
				projectDAO.getBySlug(projectSlug,
						userDAO.getByUsername(username).getId()).getId());
		if (umlModel == null) {
			throw new ResourceNotFoundException("Model not Found: " + username
					+ "/" + projectSlug + "/model/" + modelSlug);
		}
		return umlModel;
	}

}