import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpPost;
import org.springframework.util.StringUtils;

import com.yundaex.utility.stream.InputStreamUtils;


public class HttpUtil {
    public static String getRequestContent(PostMethod post) throws Exception {
        RequestEntity entity = post.getRequestEntity();
        String content = "";
        ByteArrayOutputStream baos = null;
        if (entity != null ) {
            try {
                baos = new ByteArrayOutputStream();
                entity.writeRequest(baos);
                baos.flush();
                byte[] bytes = baos.toByteArray();
                if (entity instanceof ByteArrayRequestEntity) {
                    content = new String(bytes, "US-ASCII");
                } else if(entity instanceof StringRequestEntity) {
                    String charset = post.getRequestCharSet(); 
                    content = new String(bytes, charset);
                } else {
                    content = new String(bytes,"UTF-8");
                }
            } finally {
                baos.close();
                baos = null;
            }
            
        } 
        return content;
    }
    
    public static String getRequestContent(HttpEntityEnclosingRequestBase hp) throws Exception {
        String content = "";
        Header header = hp.getEntity().getContentType();
        String contentType = header.getValue();
        String contentEncoding = "UTF-8";
        int charsetIndex = contentType.indexOf("charset=");
        if (charsetIndex == -1) {
            contentEncoding = "ISO-8859-1" ;
        } else {
            contentEncoding = contentType.substring(charsetIndex + 8);
        }
        HttpEntity httpEntity = hp.getEntity();
        InputStream inputStream = httpEntity.getContent();
        content = InputStreamUtils.getContentsAsString(inputStream, contentEncoding);
        return content;
    }
    
    public static Map<String, String> getParameterMap(PostMethod post) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        String queryString = post.getQueryString();
        map = parseKeyValue(map,queryString,"&","=");
        NameValuePair[] pairs = post.getParameters();
        for (NameValuePair nameValuePair : pairs) {
            String key = nameValuePair.getName();
            String value = nameValuePair.getValue();
            map.put(key, value);
        }
        return map;
    }
    
    public static Map<String, String> getParameterMap(HttpPost hp) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        String url = hp.getURI().toString();
        Header header = hp.getEntity().getContentType();
        String contentType = header.getValue();
        String contentEncoding = "UTF-8";
        int charsetIndex = contentType.indexOf("charset=");
        if (charsetIndex == -1) {
            contentEncoding = "ISO-8859-1" ;
        } else {
            contentEncoding = contentType.substring(charsetIndex +1);
        }
        String content = InputStreamUtils.getContentsAsString(hp.getEntity().getContent(), contentEncoding);
        map = parseUrlKeyValue(map,url,"&","=");
        if (contentType.indexOf("application/x-www-form-urlencoded") !=-1) {
            map = parseKeyValue(map,content,"&","=");
        }
        return map;
    }
    
    public static Map<String, String> getParameterMap(Map<String, String> map,String url,String content) throws Exception {
        map = parseUrlKeyValue(map,url,"&","=");
        map = parseKeyValue(map,content,"&","=");
        return map;
    }
    
    public static Map<String, String> parseUrlKeyValue(Map<String, String> map,String url,String parameterSeparator,String nameValueSeparator) {
        if (map == null) {
            map = new HashMap<String, String>();
        } else if (StringUtils.isEmpty(url)) {
            return map;
        }
        int queryIndex = url.indexOf("?");
        if (queryIndex != -1) {
            String queryString = url.substring(queryIndex + 1);
            map = parseKeyValue(map,queryString,parameterSeparator,nameValueSeparator);
        }
        return map;
    }
    
    public static Map<String, String> parseKeyValue(Map<String, String> map,String str,String parameterSeparator,String nameValueSeparator) {
        if (map == null) {
            map = new HashMap<String, String>();
        } else if (StringUtils.isEmpty(str)) {
            return map;
        }
        String[] queryPairs = str.split(parameterSeparator);
        for (String queryPair : queryPairs) {
            int index = queryPair.indexOf(nameValueSeparator);
            if (index != -1) {
                String key = queryPair.substring(0,index);
                String value = queryPair.substring(index+1);
                map.put(key, value);
            }
        }
        return map;
    }
}