package com.proofpoint.platform.sample;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
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.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import static com.proofpoint.platform.sample.PersonRepresentation.from;

@Path("/v1/person/{id: \\w+}")
public class PersonResource
{
    private final PersonStore store;

    @Inject
    public PersonResource(PersonStore store)
    {
        Preconditions.checkNotNull(store, "store must not be null");

        this.store = store;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response get(@PathParam("id") String id, @Context UriInfo uriInfo)
    {
        Preconditions.checkNotNull(id, "id must not be null");

        Person person = store.get(id);

        if (person == null) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        return Response.ok(from(person, uriInfo.getRequestUri())).build();
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public Response put(@PathParam("id") String id, PersonRepresentation person)
    {
        Preconditions.checkNotNull(id, "id must not be null");
        Preconditions.checkNotNull(person, "person must not be null");

        boolean added = store.put(id, person.toPerson());
        if (added) {
            UriBuilder uri = UriBuilder.fromResource(PersonResource.class);
            return Response.created(uri.build(id))
                            .build();
        }

        return Response.noContent().build();
    }

    @DELETE
    public Response delete(@PathParam("id") String id)
    {
        Preconditions.checkNotNull(id, "id must not be null");

        if (!store.delete(id)) {
            return Response.status(Response.Status.NOT_FOUND).build();
        }

        return Response.noContent().build();
    }
}

@@ -101,23 +101,187 @@
 gle.
-inject.Inject;%0A
+common.collect.ImmutableList;%0Aimport com.google.inject.Inject;%0A%0Aimport javax.validation.ConstraintViolation;%0Aimport javax.validation.Validation;%0Aimport javax.validation.Validator;
 %0Aimp
@@ -1770,32 +1770,331 @@
 not be null%22);%0A%0A
+        Set%3CConstraintViolation%3CPersonRepresentation%3E%3E violations = validate(person);%0A%0A        if (!violations.isEmpty()) %7B%0A            return Response.status(Response.Status.BAD_REQUEST)%0A                            .entity(messsagesFor(violations))%0A                            .build();%0A        %7D%0A%0A
         boolean 
@@ -2686,11 +2686,663 @@
 );%0A    %7D
+%0A%0A    private static Set%3CConstraintViolation%3CPersonRepresentation%3E%3E validate(PersonRepresentation person)%0A    %7B%0A        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();%0A        return validator.validate(person);%0A    %7D%0A%0A    private static List%3CString%3E messsagesFor(Collection%3C? extends ConstraintViolation%3C?%3E%3E violations)%0A    %7B%0A        ImmutableList.Builder%3CString%3E messages = new ImmutableList.Builder%3CString%3E();%0A        for (ConstraintViolation%3C?%3E violation : violations) %7B%0A            messages.add(violation.getPropertyPath().toString() + %22 %22 + violation.getMessage());%0A        %7D%0A%0A        return messages.build();%0A    %7D
 %0A%7D%0A

add validation