package mil.dds.anet.resources;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.DefaultValue;
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.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.codahale.metrics.annotation.Timed;

import io.dropwizard.auth.Auth;
import io.leangen.graphql.annotations.GraphQLArgument;
import io.leangen.graphql.annotations.GraphQLQuery;
import mil.dds.anet.AnetObjectEngine;
import mil.dds.anet.beans.Person;
import mil.dds.anet.beans.Tag;
import mil.dds.anet.beans.lists.AnetBeanList;
import mil.dds.anet.beans.search.TagSearchQuery;
import mil.dds.anet.database.TagDao;
import mil.dds.anet.utils.AnetAuditLogger;
import mil.dds.anet.utils.ResponseUtils;

@Path("/api/tags")
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
public class TagResource {

	private TagDao dao;

	public TagResource(AnetObjectEngine engine) {
		this.dao = engine.getTagDao();
	}

	@GET
	@Timed
	@GraphQLQuery(name="tags")
	@Path("/")
	public AnetBeanList<Tag> getAll(@DefaultValue("0") @QueryParam("pageNum") @GraphQLArgument(name="pageNum", defaultValue="0") int pageNum,
			@DefaultValue("100") @QueryParam("pageSize") @GraphQLArgument(name="pageSize", defaultValue="100") int pageSize) {
		return dao.getAll(pageNum, pageSize);
	}

	@GET
	@Timed
	@GraphQLQuery(name="tag")
	@Path("/{id}")
	public Tag getById(@PathParam("id") @GraphQLArgument(name="id") int id) {
		final Tag t = dao.getById(id);
		if (t == null) {
			throw new WebApplicationException(Status.NOT_FOUND);
		}
		return t;
	}

	@POST
	@Timed
	@GraphQLQuery(name="tagList")
	@Path("/search")
	public AnetBeanList<Tag> search(@GraphQLArgument(name="query") TagSearchQuery query) {
		return dao.search(query);
	}

	@GET
	@Timed
	@Path("/search")
	public AnetBeanList<Tag> search(@Context HttpServletRequest request) {
		return search(ResponseUtils.convertParamsToBean(request, TagSearchQuery.class));
	}

	@POST
	@Timed
	@Path("/new")
	@RolesAllowed("SUPER_USER")
	public Tag createTag(@Auth Person user, Tag t) {
		if (t.getName() == null || t.getName().trim().length() == 0) {
			throw new WebApplicationException("Tag name must not be empty", Status.BAD_REQUEST);
		}
		t = dao.insert(t);
		AnetAuditLogger.log("Tag {} created by {}", t, user);
		return t;

	}

	@POST
	@Timed
	@Path("/update")
	@RolesAllowed("SUPER_USER")
	public Response updateTag(@Auth Person user, Tag t) {
		final int numRows = dao.update(t);
		if (numRows == 0) {
			throw new WebApplicationException("Couldn't process tag update", Status.NOT_FOUND);
		}
		AnetAuditLogger.log("Tag {} updated by {}", t, user);
		return Response.ok().build();
	}

}

@@ -22,24 +22,47 @@
 resources;%0A%0A
+import java.util.Map;%0A%0A
 import javax
@@ -750,21 +750,134 @@
 .GraphQL
-Query
+Mutation;%0Aimport io.leangen.graphql.annotations.GraphQLQuery;%0Aimport io.leangen.graphql.annotations.GraphQLRootContext
 ;%0Aimport
@@ -1148,16 +1148,52 @@
 Logger;%0A
+import mil.dds.anet.utils.DaoUtils;%0A
 import m
@@ -2527,16 +2527,351 @@
 ag t) %7B%0A
+%09%09return createTagCommon(user, t);%0A%09%7D%0A%0A%09@GraphQLMutation(name=%22createTag%22)%0A%09@RolesAllowed(%22SUPER_USER%22)%0A%09public Tag createTag(@GraphQLRootContext Map%3CString, Object%3E context, @GraphQLArgument(name=%22tag%22) Tag t) %7B%0A%09%09return createTagCommon(DaoUtils.getUserFromContext(context), t);%0A%09%7D%0A%0A%09private Tag createTagCommon(Person user, Tag t) %7B%0A
 %09%09if (t.
@@ -3108,17 +3108,16 @@
 turn t;%0A
-%0A
 %09%7D%0A%0A%09@PO
@@ -3225,24 +3225,479 @@
 r, Tag t) %7B%0A
+%09%09updateTagCommon(user, t);%0A%09%09return Response.ok().build();%0A%09%7D%0A%0A%09@GraphQLMutation(name=%22updateTag%22)%0A%09@RolesAllowed(%22SUPER_USER%22)%0A%09public Integer updateTag(@GraphQLRootContext Map%3CString, Object%3E context, @GraphQLArgument(name=%22tag%22) Tag t) %7B%0A%09%09// GraphQL mutations *have* to return something, so we return the number of updated rows%0A%09%09return updateTagCommon(DaoUtils.getUserFromContext(context), t);%0A%09%7D%0A%0A%09private int updateTagCommon(Person user, Tag t) %7B%0A
 %09%09final int 
@@ -3899,37 +3899,23 @@
 %09return 
-Response.ok().build()
+numRows
 ;%0A%09%7D%0A%0A%7D%0A

Add missing GraphQL mutations used by tests