package nl.erasmusmc.mieur.biosemantics.advance.codemapper.rest;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;

import nl.erasmusmc.mieur.biosemantics.advance.codemapper.CodeMapperException;
import nl.erasmusmc.mieur.biosemantics.advance.codemapper.authentification.User;
import nl.erasmusmc.mieur.biosemantics.advance.codemapper.persistency.PersistencyApi;

import org.apache.log4j.Logger;

@Path("persistency")
public class PersistencyResource {

	private static Logger logger = Logger.getLogger("CodeMapperWebService");

	private @Context SecurityContext sc;

	private PersistencyApi api = CodeMapperApplication.getPersistencyApi();

	private static void assertUserInProject(User user, String project) {
		if (user == null || !user.getProjects().contains(project))
			throw new UnauthorizedException();
	}

	@GET
	@Path("projects")
	@Produces(MediaType.APPLICATION_JSON)
	public List<String> getProjects(@Context HttpServletRequest request, @Context User user) {
		AuthentificationResource.assertAuthentificated(user);
		try {
			if (user.isAdmin())
				return api.getProjects();
			else
				return api.getProjects(user.getUsername());
		} catch (CodeMapperException e) {
			System.err.println("Couldn't get projects");
			e.printStackTrace();
			throw new InternalServerErrorException(e);
		}
	}

	@GET
	@Path("projects/{project}/case-definitions")
	@Produces(MediaType.APPLICATION_JSON)
	public List<String> getCaseDefinitionNames(@PathParam("project") String project, @Context User user) {
		assertUserInProject(user, project);
		try {
			return api.getCaseDefinitionsNames(project);
		} catch (CodeMapperException e) {
			System.err.println("Couldn't get case definitions");
			e.printStackTrace();
			throw new InternalServerErrorException(e);
		}
	}

	@GET
	@Path("projects/{project}/case-definitions/{name}")
	@Produces(MediaType.APPLICATION_JSON)
	public String getCaseDefinition(@PathParam("project") String project, @PathParam("name") String name, @Context User user) {
		logger.debug(String.format("Get case definition %s", name));
		assertUserInProject(user, project);
		try {
			String stateJson = api.getCaseDefinition(project, name);
			if (stateJson != null)
				return stateJson;
			else
				throw new NotFoundException();
		} catch (CodeMapperException e) {
			System.err.println("Couldn't get case definition");
			e.printStackTrace();
			throw new InternalServerErrorException(e);
		}
	}

	@POST
	@Path("projects/{project}/case-definitions/{name}")
	@Produces(MediaType.APPLICATION_JSON)
	public void setCaseDefinition(@PathParam("project") String project, @PathParam("name") String name, @FormParam("state") String stateJson, @Context User user) {
		logger.debug(String.format("Set case definition %s", name));
		assertUserInProject(user, project);
		try {
			api.setCaseDefinition(project, name, stateJson);
		} catch (CodeMapperException e) {
			System.err.println("Couldn't save case definition");
			e.printStackTrace();
			throw new InternalServerErrorException(e);
		}
	}
}

@@ -1041,29 +1041,36 @@
 d assert
-UserIn
+AdminOr
 Project
+Member
 (User us
@@ -1097,27 +1097,86 @@
 %7B%0A%09%09
-if (user == null %7C%7C
+AuthentificationResource.assertAuthentificated(user);%0A%09%09if (!user.isAdmin() &&
  !us
@@ -1943,37 +1943,44 @@
 ) %7B%0A%09%09assert
-UserIn
+AdminOr
 Project
+Member
 (user, proje
@@ -2500,37 +2500,44 @@
 ));%0A%09%09assert
-UserIn
+AdminOr
 Project
+Member
 (user, proje
@@ -3204,21 +3204,28 @@
 sert
-UserIn
+AdminOr
 Project
+Member
 (use

Fix for admin to access PersistencyResource