package com.k_int.ciim.ui.resources;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import com.k_int.ciim.ui.exceptions.MissingResourceException;
import com.k_int.ciim.ui.exceptions.NotAuthorisedException;
import com.k_int.ciim.ui.exceptions.ResourceCreationException;
import com.k_int.ciim.ui.json.UserJSON;
import com.k_int.ciim.ui.kernel.IdentServiceQueryCore;
import com.k_int.ciim.ui.kernel.IdentServiceTransactionCore;
import com.k_int.ciim.ui.ref.RoleDefinitionEnum;
import com.sun.jersey.api.view.ImplicitProduces;
import com.sun.jersey.api.view.Viewable;

@XmlRootElement
@ImplicitProduces("text/html;qs=5") //for FireFox?
@XmlAccessorType(XmlAccessType.FIELD)
@Path("/resources/users/{username}")
public class UserResource extends AbstractResource
{
	@XmlTransient
	private IdentServiceQueryCore isqc = null;
	@XmlTransient
	private IdentServiceTransactionCore istc = null;
	
	private UserJSON resource = null;
	
	/* App context setters */
	public void setIdentServiceQueryCore(IdentServiceQueryCore isqc){ this.isqc = isqc; }
	public void setIdentServiceTransactionCore(IdentServiceTransactionCore istc){ this.istc = istc; }
	  
	public UserResource(){;}
	
	@GET
	@Produces({MediaType.TEXT_HTML,MediaType.APPLICATION_XHTML_XML})
	public Viewable getHtml(@PathParam("username") String username) 
	{
		resource = new UserJSON(isqc.getUser(username), isqc.getPermissions(username));
		
		return new Viewable("index",this);
	}
	
	@GET
	@Produces("application/json")
	public UserJSON getJson(@PathParam("username") String username) 
	{		
		return new UserJSON(isqc.getUser(username), isqc.getPermissions(username));
	}
	
	@POST 
	@Consumes("application/x-www-form-urlencoded")
	@Produces({MediaType.TEXT_PLAIN})
	public String action(@PathParam("username") String username, @QueryParam("action") String action, MultivaluedMap<String, String> form_params)
	{
		String retval = null;
		
		if(action.equalsIgnoreCase("updatePermission"))
		{
			retval = updatePermission(username, form_params);
		}
		else if(action.equalsIgnoreCase("changePassword"))
		{
			retval = changePassword(username, form_params);
		}
		else if(action.equalsIgnoreCase("update"))
		{
			retval = updateUser(username, form_params);
		}

		return retval;
	}
	
	@POST 
	@Produces({MediaType.TEXT_PLAIN})
	public String action(@PathParam("username") String username, @QueryParam("action") String action)
	{
		String retval = null;
		
		if(action.equalsIgnoreCase("toggleActive"))
		{
			retval = toggleActiveStatus(username);
		}
		else if(action.equalsIgnoreCase("resetPassword"))
		{
			retval = resetPassword(username);
		}	
		
		return retval;
	}
	
	@Path("/permissions")
	@POST
	@Produces({MediaType.TEXT_PLAIN})
	public String hasPermission(	@PathParam("username") String username,
									@QueryParam("context") String context_id, 
									@QueryParam("context_link") String context_link_id, 
									@QueryParam("type") String type)
	{
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			return Boolean.TRUE.toString();
		}

		return new Boolean(isqc.hasPermission(username, context_id, context_link_id, type)).toString();
	}
	
	private String updatePermission(@PathParam("username") String username, MultivaluedMap<String, String> form_params)
	{
		String retval= "Failed to add permissions.";
		
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			try
			{
				if(istc.updatePermissions(username, form_params))
				{
					retval = "Successfully updated permissions.";
				}
			}
			catch(MissingResourceException mre)
			{
				throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(mre.getMessage()).type("text/plain").build());
			}
		}
		else
		{
			throw new NotAuthorisedException();
		}
		
		return retval;
	}
	
	private String changePassword(String username, MultivaluedMap<String, String> form_params)
	{
		String retval= "Failed to change password.";
		
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			try
			{
				if(istc.changePassword(username, form_params))
				{
					retval = "Successfully changed password.";
				}
			}
			catch(ResourceCreationException rce)
			{
				throw new WebApplicationException(Response.status(Status.CONFLICT).entity(rce.getMessage()).type("text/plain").build());
			}
		}
		else
		{
			throw new NotAuthorisedException();
		}
		
		return retval;
	}
	
	private String updateUser(String username, MultivaluedMap<String, String> form_params)
	{
		String retval= "Failed to update user.";
		
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			try
			{
				if(istc.updateUser(username, form_params))
				{
					retval = "Successfully updated user.";
				}
			}
			catch(ResourceCreationException rce)
			{
				throw new WebApplicationException(Response.status(Status.CONFLICT).entity(rce.getMessage()).type("text/plain").build());
			}
			catch(MissingResourceException mre)
			{
				throw new WebApplicationException(Response.status(Status.CONFLICT).entity(mre.getMessage()).type("text/plain").build());
			}
		}
		else
		{
			throw new NotAuthorisedException();
		}
		
		return retval;
	}
	
	private String toggleActiveStatus(String username)
	{
		String retval = "Failed to modify user.";
		
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			try
			{
				retval = istc.toggleUserActiveStatus(username);
			}
			catch(MissingResourceException mre)
			{
				throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(mre.getMessage()).type("text/plain").build());
			}
		}
		else
		{
			throw new NotAuthorisedException();
		}
		
		return retval;
	}
	
	private String resetPassword(String username)
	{
		String retval = "Failed to reset password.";
		
		if(meetsRoleRequirement(RoleDefinitionEnum.SUPER.toString()))
		{
			try
			{
				retval = istc.resetPassword(username);
			}
			catch(MissingResourceException mre)
			{
				throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(mre.getMessage()).type("text/plain").build());
			}
		}
		else
		{
			throw new NotAuthorisedException();
		}
		
		return retval;
	}
		
	public UserJSON getResource() 
	{
		return resource;
	}
	
	public void setResource(UserJSON resource) 
	{
		this.resource = resource;
	}
	
	
}
