package com.ning.http.client.providers;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Collections;
import java.util.List;

import com.ning.http.client.Cookie;
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
import com.ning.http.client.HttpResponseBodyPart;
import com.ning.http.client.HttpResponseHeaders;
import com.ning.http.client.HttpResponseStatus;
import com.ning.http.client.Response;
import com.ning.http.util.AsyncHttpProviderUtils;

public abstract class ResponseBase implements Response
{
    protected final static String DEFAULT_CHARSET = "ISO-8859-1";

    protected final List<HttpResponseBodyPart> bodyParts;
    protected final HttpResponseHeaders headers;
    protected final HttpResponseStatus status;
    private List<Cookie> cookies;

    protected ResponseBase(HttpResponseStatus status,
            HttpResponseHeaders headers,
            List<HttpResponseBodyPart> bodyParts)
    {
        this.bodyParts = bodyParts;
        this.headers = headers;
        this.status = status;
    }

    /* @Override */
    public final int getStatusCode() {
        return status.getStatusCode();
    }

    /* @Override */
    public final String getStatusText() {
        return status.getStatusText();
    }


    /* @Override */
    public final URI getUri() /*throws MalformedURLException*/ {
        return status.getUrl();
    }

    /* @Override */
    public final String getContentType() {
        return headers != null? getHeader("Content-Type"): null;
    }

    /* @Override */
    public final String getHeader(String name) {
        return headers != null? getHeaders().getFirstValue(name): null;
    }

    /* @Override */
    public final List<String> getHeaders(String name) {
        return headers != null? getHeaders().get(name): null;
    }

    /* @Override */
    public final FluentCaseInsensitiveStringsMap getHeaders() {
        return headers != null? headers.getHeaders(): new FluentCaseInsensitiveStringsMap();
    }

    /* @Override */
    public final boolean isRedirected() {
        return (status.getStatusCode() >= 300) && (status.getStatusCode() <= 399);
    }
    
    /* @Override */
    public byte[] getResponseBodyAsBytes() throws IOException {
        return AsyncHttpProviderUtils.contentToBytes(bodyParts);
    }

    /* @Override */
    public String getResponseBody() throws IOException {
        return getResponseBody(DEFAULT_CHARSET);
    }

    public String getResponseBody(String charset) throws IOException {
        return AsyncHttpProviderUtils.contentToString(bodyParts, calculateCharset(charset));
    }

    /* @Override */
    public InputStream getResponseBodyAsStream() throws IOException {
        return AsyncHttpProviderUtils.contentAsStream(bodyParts);
    }
    
    protected abstract List<Cookie> buildCookies();
    
    public List<Cookie> getCookies() {

        if (headers == null) {
            return Collections.emptyList();
        }

        if (cookies == null) {
            cookies = buildCookies();
        }
        return cookies;

    }

    protected String calculateCharset(String charset) {
        
    	if (charset == null) {
	        String contentType = getContentType();
	        if (contentType != null) {
	            charset = AsyncHttpProviderUtils.parseCharset(contentType);
	        } else {
	        	charset = DEFAULT_CHARSET;
	        }
    	}

        return charset;
    }

    public boolean hasResponseStatus() {
        return status != null;
    }

    public boolean hasResponseHeaders() {
        return headers != null && !headers.getHeaders().isEmpty();
    }

    public boolean hasResponseBody() {
        return bodyParts != null && !bodyParts.isEmpty();
    }
}

@@ -3163,17 +3163,20 @@
    %0A    
-%09
+    
 if (char
@@ -3190,25 +3190,24 @@
 null) %7B%0A
-%09
         
 String c
@@ -3198,16 +3198,17 @@
         
+%09
 String c
@@ -3238,25 +3238,24 @@
 Type();%0A
-%09
         
 if (cont
@@ -3242,24 +3242,25 @@
 ();%0A        
+%09
 if (contentT
@@ -3275,22 +3275,17 @@
 ull)
- %7B%0A%09  
+%0A
         
   ch
@@ -3280,18 +3280,18 @@
         
-  
+%09%09
 charset 
@@ -3345,65 +3345,41 @@
 pe);
-%0A%09        %7D else %7B%0A%09        %09charset = DEFAULT_CHARSET;%0A%09
+ // parseCharset can return null%0A
     
@@ -3388,16 +3388,8 @@
   %7D%0A
-    %09%7D%0A%0A
     
@@ -3406,16 +3406,50 @@
  charset
+ != null? charset: DEFAULT_CHARSET
 ;%0A    %7D%0A

Fix charset computation when it's not specified in contentType