package com.github.dockerjava.jaxrs.util;

import java.io.EOFException;
import java.io.IOException;
import java.nio.charset.Charset;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.core.MediaType;

import org.apache.commons.io.IOUtils;

import com.github.dockerjava.api.BadRequestException;
import com.github.dockerjava.api.ConflictException;
import com.github.dockerjava.api.DockerException;
import com.github.dockerjava.api.InternalServerErrorException;
import com.github.dockerjava.api.NotAcceptableException;
import com.github.dockerjava.api.NotFoundException;
import com.github.dockerjava.api.NotModifiedException;
import com.github.dockerjava.api.UnauthorizedException;

/**
 * This {@link ClientResponseFilter} implementation detects http status codes and throws {@link DockerException}s 
 *
 * @author marcus
 *
 */
public class ResponseStatusExceptionFilter implements ClientResponseFilter {


    @Override
    public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
    	int status = responseContext.getStatus();
		switch (status) {
		case 200:
		case 201:	
		case 204:
			return;
		case 304:
			throw new NotModifiedException(getBodyAsMessage(responseContext));
		case 400:
			throw new BadRequestException(getBodyAsMessage(responseContext));
		case 401:
			throw new UnauthorizedException(getBodyAsMessage(responseContext));	
		case 404:
			throw new NotFoundException(getBodyAsMessage(responseContext));
		case 406:
			throw new NotAcceptableException(getBodyAsMessage(responseContext));
		case 409:
			throw new ConflictException(getBodyAsMessage(responseContext));
		case 500:
			throw new InternalServerErrorException(getBodyAsMessage(responseContext));
		default:
			throw new DockerException(getBodyAsMessage(responseContext), status);
		}
    }

	public String getBodyAsMessage(ClientResponseContext responseContext)
			throws IOException {
	    if (responseContext.hasEntity()) {
	        int contentLength = responseContext.getLength();
	        if (contentLength != -1) {
	            byte[] buffer = new byte[contentLength];
	            try {
	                IOUtils.readFully(responseContext.getEntityStream(), buffer);
	            }
	            catch (EOFException e) {
	                return null;
	            }
	            Charset charset = null;
	            MediaType mediaType = responseContext.getMediaType();
	            if (mediaType != null) {
	                String charsetName = mediaType.getParameters().get("charset");
	                if (charsetName != null) {
	                    try {
	                        charset = Charset.forName(charsetName);
                        }
                        catch (Exception e) {
                            //Do noting...
                        }
	                }
	            }
	            if (charset == null) {
                    charset = Charset.defaultCharset();
	            }
	            String message = new String(buffer, charset);
	            return message;
	        }
	    }
	    return null;
	}
}

@@ -445,32 +445,88 @@
 flictException;%0A
+import com.github.dockerjava.api.DeviceIsBusyException;%0A
 import com.githu
@@ -1897,16 +1897,99 @@
 text));%0A
+%09%09case 599:%0A%09%09%09throw new DeviceIsBusyException(getBodyAsMessage(responseContext));%0A
 %09%09defaul

Throw DeviceIsBusyException when response status code is 599.