package org.jboss.resteasy.test.resource.param.resource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

public class MultiValuedParamPersonResource {

    @Path("queryParam")
    public static class QueryParamResource {

        // http://xxx/queryParam/customConversion_list?person=George,Jack,John
        @GET
        @Path("customConversion_list")
        public Response customConversion_list(@QueryParam("person") List<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_arrayList?person=George,Jack,John
        @GET
        @Path("customConversion_arrayList")
        public Response customConversion_arrayList(
                @QueryParam("person") ArrayList<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_set?person=George,Jack,John
        @GET
        @Path("customConversion_set")
        public Response customConversion_set(@QueryParam("person") Set<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_hashSet?person=George,Jack,John
        @GET
        @Path("customConversion_hashSet")
        public Response customConversion_hashSet(@QueryParam("person") HashSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_sortedSet?person=George,Jack,John
        @GET
        @Path("customConversion_sortedSet")
        public Response customConversion_sortedSet(
                @QueryParam("person") SortedSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_treeSet?person=George,Jack,John
        @GET
        @Path("customConversion_treeSet")
        public Response customConversion_treeSet(@QueryParam("person") TreeSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // http://xxx/queryParam/customConversion_array?person=George,Jack,John
        @GET
        @Path("customConversion_array")
        public Response customConversion_array(@QueryParam("person") MultiValuedParamPersonWithConverter[] people) {
            return Response.ok(formatPeopleWithConverter(Arrays.asList(people))).build();
        }
    }

    @Path("headerParam")
    public static class HeaderParamResource {

        // person:George,Jack,John
        @GET
        @Path("customConversion_list")
        public Response customConversion_list(@HeaderParam("person") List<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_arrayList")
        public Response customConversion_arrayList(
                @HeaderParam("person") ArrayList<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_set")
        public Response customConversion_set(@HeaderParam("person") Set<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_hashSet")
        public Response customConversion_hashSet(@HeaderParam("person") HashSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_sortedSet")
        public Response customConversion_sortedSet(
                @HeaderParam("person") SortedSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_treeSet")
        public Response customConversion_treeSet(@HeaderParam("person") TreeSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_array")
        public Response customConversion_array(@HeaderParam("person") MultiValuedParamPersonWithConverter[] people) {
            return Response.ok(formatPeopleWithConverter(Arrays.asList(people))).build();
        }
    }

    @Path("matrixParam")
    public static class MatrixParamResource {

        // person:George,Jack,John
        @GET
        @Path("customConversion_list")
        public Response customConversion_list(@MatrixParam("person") List<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_arrayList")
        public Response customConversion_arrayList(
                @MatrixParam("person") ArrayList<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_set")
        public Response customConversion_set(@MatrixParam("person") Set<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_hashSet")
        public Response customConversion_hashSet(@MatrixParam("person") HashSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_sortedSet")
        public Response customConversion_sortedSet(
                @MatrixParam("person") SortedSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_treeSet")
        public Response customConversion_treeSet(@MatrixParam("person") TreeSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_array")
        public Response customConversion_array(@MatrixParam("person") MultiValuedParamPersonWithConverter[] people) {
            return Response.ok(formatPeopleWithConverter(Arrays.asList(people))).build();
        }
    }

    @Path("cookieParam")
    public static class CookieParamResource {

        // person:George,Jack,John
        @GET
        @Path("customConversion_list")
        public Response customConversion_list(@CookieParam("person") List<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_arrayList")
        public Response customConversion_arrayList(
                @CookieParam("person") ArrayList<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_set")
        public Response customConversion_set(@CookieParam("person") Set<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_hashSet")
        public Response customConversion_hashSet(@CookieParam("person") HashSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_sortedSet")
        public Response customConversion_sortedSet(
                @CookieParam("person") SortedSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_treeSet")
        public Response customConversion_treeSet(@CookieParam("person") TreeSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_array")
        public Response customConversion_array(@CookieParam("person") MultiValuedParamPersonWithConverter[] people) {
            return Response.ok(formatPeopleWithConverter(Arrays.asList(people))).build();
        }
    }

    @Path("pathParam")
    public static class PathParamResource {

        // person:George,Jack,John
        @GET
        @Path("customConversion_list/{person}")
        public Response customConversion_list(@PathParam("person") List<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_arrayList/{person}")
        public Response customConversion_arrayList(@PathParam("person") ArrayList<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_set/{person}")
        public Response customConversion_set(@PathParam("person") Set<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_hashSet/{person}")
        public Response customConversion_hashSet(@PathParam("person") HashSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_sortedSet/{person}")
        public Response customConversion_sortedSet(@PathParam("person") SortedSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_treeSet/{person}")
        public Response customConversion_treeSet(@PathParam("person") TreeSet<MultiValuedParamPersonWithConverter> people) {
            return Response.ok(formatPeopleWithConverter(people)).build();
        }

        // person:George,Jack,John
        @GET
        @Path("customConversion_array/{person}")
        public Response customConversion_array(@PathParam("person") MultiValuedParamPersonWithConverter[] people) {
            return Response.ok(formatPeopleWithConverter(Arrays.asList(people))).build();
        }
    }

    private static String formatPeopleWithConverter(Collection<MultiValuedParamPersonWithConverter> people) {
        StringBuilder stringBuilder = new StringBuilder();
        int personCount = people.size();
        int i = 0;
        for (MultiValuedParamPersonWithConverter person : new TreeSet<>(people)) {
            stringBuilder.append(person.toString());
            ++i;
            if (i < personCount) {
                stringBuilder.append(",");
            }
        }
        return stringBuilder.toString();
    }
}
