package org.bench4q.recorder.httpcapture.generator;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.ChunkedInputStream;
import org.apache.commons.httpclient.ChunkedOutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.log4j.Logger;
import org.bench4q.recorder.httpcapture.ResponseModel;

public class ResponseParser {
	private Logger logger = Logger.getLogger(ResponseParser.class);
	private byte[] response;
	private ResponseHeader responseHeader;
	private String responseBody;

	private byte[] getResponse() {
		return response;
	}

	private void setResponse(byte[] response) {
		this.response = response;
	}

	public ResponseHeader getResponseHeader() {
		return responseHeader;
	}

	private void setResponseHeader(ResponseHeader responseHeader) {
		this.responseHeader = responseHeader;
	}

	public String getResponseBody() {
		return responseBody;
	}

	private void setResponseBody(String responseBody) {
		this.responseBody = responseBody;
	}

	public ResponseParser(ResponseModel response) {
		this.setResponse(response.getResponse());
		this.setResponseHeader(parseResponseHeader(response.getConn()));
		if (this.getResponseHeader().isValidResponseHeader()
				&& this.getResponseHeader().isHtmlContentType()) {
			this.parseResponseBody();

		}
	}

	private ResponseHeader parseResponseHeader(
			HttpURLConnection httpURLConnection) {
		ResponseHeader result = new ResponseHeader();
		if (httpURLConnection == null)
			return result;
		result.setContentEncoding(httpURLConnection.getContentEncoding());
		result.setContentLength(httpURLConnection.getContentLength());
		try {
			result.setRespCode(httpURLConnection.getResponseCode());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		result.setTransferEncoding(parseTransferEncoding(httpURLConnection));
		result.setCharset(parseCharset(httpURLConnection));
		result.setContentType(parseContentType(httpURLConnection));
		return result;
	}

	private String parseCharset(HttpURLConnection httpURLConnection) {

		String ret = null;
		String value = httpURLConnection.getHeaderField("Content-Type");
		int pos;
		if (value != null && (pos = value.indexOf("charset=")) != -1) {
			ret = value.substring(pos + 8);
		}

		return ret;
	}

	private String parseContentType(HttpURLConnection httpURLConnection) {
	
		String ret = null;
		String value = httpURLConnection.getHeaderField("Content-Type");
		int pos;
		if (value != null) {
			if ((pos = value.indexOf(";")) != -1) {
				ret = value.substring(0, pos);
			} else {

				ret = value;
			}
		}

		return ret;
	}


	private String parseTransferEncoding(HttpURLConnection httpURLConnection) {
	
		return httpURLConnection.getHeaderField("Transfer-Encoding");
	}



	private void parseResponseBody() {
		ContentDecoder contentDecoder = ContentDecoder.createDecoder(this
				.getResponseHeader().getContentEncoding());
		byte[] contentBodyAfterDecoded = null;

		contentBodyAfterDecoded = contentDecoder
				.decodeContent(new ByteArrayInputStream(this.getResponse(), 0,
						this.getResponse().length));
		if (contentBodyAfterDecoded == null) {
			return;
		}
		Charset charset = null;
		try {
			charset = Charset.forName(this.getResponseHeader().getCharset());
		} catch (Exception e) {
			charset = Charset.forName("utf-8");
			logger.error(e, e);
		}
		this.setResponseBody(new String(contentBodyAfterDecoded, charset));
	}
	
	public byte[] encodeCoent(String responseBody){
		ContentEncoder contentEncoder = ContentEncoder.createEncoder(this
				.getResponseHeader().getContentEncoding());
		Charset charset = null;
		try {
			charset = Charset.forName(this.getResponseHeader().getCharset());
		} catch (Exception e) {
			charset = Charset.forName("utf-8");
			logger.error(e, e);
		}
		byte[] responseBytes = responseBody.getBytes(charset);
		responseBytes = contentEncoder.encoderContent(responseBytes);
	
		return responseBytes;
	}
}
