/*
 * Copyright 2010-2013 Ning, Inc.
 *
 * Ning licenses this file to you under the Apache License, version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at:
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package org.killbill.billing.jaxrs.util;

import java.net.URI;
import java.util.Map;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.killbill.billing.jaxrs.json.ProfilingDataJson;
import org.killbill.billing.jaxrs.resources.JaxRsResourceBase;
import org.killbill.billing.jaxrs.resources.JaxrsResource;
import org.killbill.commons.profiling.Profiling;
import org.killbill.commons.profiling.ProfilingData;

public class JaxrsUriBuilder {

    public Response buildResponse(final UriInfo uriInfo, final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId) {
        final UriBuilder uriBuilder = UriBuilder.fromResource(theClass)
                                                .path(theClass, getMethodName)
                                                .scheme(uriInfo.getAbsolutePath().getScheme())
                                                .host(uriInfo.getAbsolutePath().getHost())
                                                .port(uriInfo.getAbsolutePath().getPort());

        final URI location = objectId != null ? uriBuilder.build(objectId) : uriBuilder.build();
        return Response.created(location).build();
    }

    public URI nextPage(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Long nextOffset, final Long limit, final Map<String, String> params) {
        if (nextOffset == null || limit == null) {
            // End of pagination?
            return null;
        }

        final UriBuilder uriBuilder = UriBuilder.fromResource(theClass)
                                                .path(theClass, getMethodName)
                                                .queryParam(JaxRsResourceBase.QUERY_SEARCH_OFFSET, nextOffset)
                                                .queryParam(JaxRsResourceBase.QUERY_SEARCH_LIMIT, limit);
        for (final String key : params.keySet()) {
            uriBuilder.queryParam(key, params.get(key));
        }
        return uriBuilder.build();
    }

    public Response buildResponse(final Class<? extends JaxrsResource> theClass, final String getMethodName, final Object objectId, final String baseUri) {

        // Let's build a n absolute location for cross resources
        // See Jersey ContainerResponse.setHeaders
        final StringBuilder tmp = new StringBuilder(baseUri.substring(0, baseUri.length() - 1));
        tmp.append(UriBuilder.fromResource(theClass).path(theClass, getMethodName).build(objectId).toString());
        final URI newUriFromResource = UriBuilder.fromUri(tmp.toString()).build();
        final Response.ResponseBuilder ri = Response.created(newUriFromResource);
        final Object obj = new Object() {
            @SuppressWarnings(value = "all")
            public URI getUri() {
                return newUriFromResource;
            }
        };
        return ri.entity(obj).build();
    }
}

@@ -703,16 +703,41 @@
 l.Map;%0A%0A
+import javax.ws.rs.Path;%0A
 import j
@@ -758,24 +758,24 @@
 e.Response;%0A
-
 import javax
@@ -836,66 +836,8 @@
 o;%0A%0A
-import org.killbill.billing.jaxrs.json.ProfilingDataJson;%0A
 impo
@@ -957,110 +957,8 @@
 rce;
-%0Aimport org.killbill.commons.profiling.Profiling;%0Aimport org.killbill.commons.profiling.ProfilingData;
 %0A%0Apu
@@ -1174,32 +1174,35 @@
 er uriBuilder = 
+get
 UriBuilder.fromR
@@ -1199,159 +1199,33 @@
 lder
-.fromResource(theClass)%0A                                                .path(theClass, getMethodName)%0A                                                
+(theClass, getMethodName)
 .sch
@@ -1315,16 +1315,44 @@
         
+          
+                  
 .host(ur
@@ -1382,24 +1382,52 @@
 .getHost())%0A
+                            
             
@@ -1997,16 +1997,19 @@
 ilder = 
+get
 UriBuild
@@ -2014,159 +2014,33 @@
 lder
-.fromResource(theClass)%0A                                                .path(theClass, getMethodName)%0A                                                
+(theClass, getMethodName)
 .que
@@ -2098,16 +2098,44 @@
 Offset)%0A
+                            
         
@@ -2781,16 +2781,19 @@
 .append(
+get
 UriBuild
@@ -2798,36 +2798,8 @@
 lder
-.fromResource(theClass).path
 (the
@@ -3203,16 +3203,16 @@
      %7D;%0A
-
         
@@ -3247,11 +3247,842 @@
 );%0A    %7D
+%0A%0A    private UriBuilder getUriBuilder(final Class%3C? extends JaxrsResource%3E theClassMaybeEnhanced, final String getMethodName) %7B%0A        final Class theClass = getNonEnhancedClass(theClassMaybeEnhanced);%0A        return UriBuilder.fromResource(theClass).path(theClass, getMethodName);%0A    %7D%0A%0A    private Class getNonEnhancedClass(final Class%3C? extends JaxrsResource%3E theClassMaybeEnhanced) %7B%0A        // If Guice is proxying the class for example ($EnhancerByGuice$), we want the real class.%0A        // See https://java.net/projects/jersey/lists/users/archive/2008-10/message/291%0A        Class theClass = theClassMaybeEnhanced;%0A        while (theClass.getAnnotation(Path.class) == null && JaxRsResourceBase.class.isAssignableFrom(theClass)) %7B%0A            theClass = theClass.getSuperclass();%0A        %7D%0A%0A        return theClass;%0A    %7D
 %0A%7D%0A

fix tests failures