package org.openstack.connector;

import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.filter.LoggingFilter;
import org.openstack.base.client.OpenStackClientConnector;
import org.openstack.base.client.OpenStackNotAuthorized;
import org.openstack.base.client.OpenStackRequest;

import com.google.common.reflect.TypeToken;

public class JaxRs20Connector implements OpenStackClientConnector {

	protected Client client = OpenStack.CLIENT;

	@Override
	public <T> T execute(OpenStackRequest request, Class<T> responseType) {
		WebTarget target = client.target(request.endpoint()).path(request.path());
		target.register(new LoggingFilter(Logger.getLogger("os"),10000));
		Invocation.Builder invocation = target.request();
		for(Map.Entry<String, List<Object>> h : request.headers().entrySet()) {
			StringBuilder sb = new StringBuilder();
			for(Object v : h.getValue()) {
				sb.append(String.valueOf(v));
			}
			invocation.header(h.getKey(), sb);
		}
		
		try {
			if (request.entity() != null) {
				return invocation.method(request.method().name(), Entity
						.entity(request.entity().getEntity(), request.entity()
								.getContentType()), responseType);
			} else {
				return invocation.method(request.method().name(), responseType);
			}
		} catch (NotAuthorizedException e) {
			throw new OpenStackNotAuthorized();
		}
	}

	@Override
	public void execute(OpenStackRequest request) {
		execute(request, Response.class);
		
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T execute(OpenStackRequest request, TypeToken<T> typeToken) {
		return (T) execute(request, typeToken.getClass());
	}
	
}

@@ -1222,65 +1222,229 @@
 %09%09%7D%0A
-%09%09
 %0A%09%09
-try %7B%0A%09%09%09if (request.entity() != null) %7B%0A%09%09%09%09return 
+Entity%3C?%3E entity = (request.entity() == null) ? null : Entity%0A%09%09%09%09.entity(request.entity().getEntity(), request.entity()%0A%09%09%09%09%09%09.getContentType());%0A%0A%09%09try %7B%0A%09%09%09if (entity != null) %7B%0A%09%09%09%09if (responseType == null) %7B%0A%09%09%09%09%09
 invo
@@ -1486,119 +1486,208 @@
 (), 
-E
+e
 ntity
+);
 %0A%09%09%09%09
-%09%09.entity(request.entity().getE
+%7D else %7B%0A%09%09%09%09%09return invocation.method(request.method().name(), e
 ntity
-()
 , re
-quest.entity()%0A%09%09%09%09%09%09%09%09.getContentType()), responseType
+sponseType);%0A%09%09%09%09%7D%0A%09%09%09%7D else %7B%0A%09%09%09%09if (responseType == null) %7B%0A%09%09%09%09%09invocation.method(request.method().name()
 );%0A
+%09
 %09%09%09%7D
@@ -1690,24 +1690,25 @@
 %09%09%09%7D else %7B%0A
+%09
 %09%09%09%09return i
@@ -1764,16 +1764,22 @@
 eType);%0A
+%09%09%09%09%7D%0A
 %09%09%09%7D%0A%09%09%7D
@@ -1856,16 +1856,32 @@
 d();%0A%09%09%7D
+%0A%0A%09%09return null;
 %0A%09%7D%0A%0A%09@O

support the empty server responses