package org.jim.common.http;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;

/**
 *
 * @author wchao
 * 2017年8月4日 上午9:41:12
 */
public class HttpResponseEncoder {
	public static enum Step {
		firstLine, header, body
	}

	private static Logger log = LoggerFactory.getLogger(HttpResponseEncoder.class);

	public static final int MAX_HEADER_LENGTH = 20480;

	/**
	 *
	 * @param httpResponse
	 * @param groupContext
	 * @param channelContext
	 * @param skipCookie true: 忽略掉cookie部分的编码
	 * @return
	 * @author wchao
	 */
	public static ByteBuffer encode(HttpResponse httpResponse, GroupContext groupContext, ChannelContext channelContext, boolean skipCookie) {
		byte[] encodedBytes = httpResponse.getEncodedBytes();
		if (encodedBytes != null) {
			ByteBuffer ret = ByteBuffer.wrap(encodedBytes);
			ret.position(ret.limit());
			return ret;
		}

		int bodyLength = 0;
		byte[] body = httpResponse.getBody();
		if (body != null) {
			bodyLength = body.length;
		}

		StringBuilder sb = new StringBuilder(256);

		HttpResponseStatus httpResponseStatus = httpResponse.getStatus();
		//		httpResponseStatus.get
		sb.append("HTTP/1.1 ").append(httpResponseStatus.getStatus()).append(" ").append(httpResponseStatus.getDescription()).append("\r\n");

		Map<String, String> headers = httpResponse.getHeaders();
		if (headers != null && headers.size() > 0) {
			headers.put(HttpConst.ResponseHeaderKey.Content_Length, bodyLength + "");
			Set<Entry<String, String>> set = headers.entrySet();
			for (Entry<String, String> entry : set) {
				sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
			}
		}

		if (!skipCookie) {
			//处理cookie
			List<Cookie> cookies = httpResponse.getCookies();
			if (cookies != null) {
				for (Cookie cookie : cookies) {
					sb.append(HttpConst.ResponseHeaderKey.Set_Cookie).append(": ");
					sb.append(cookie.toString());
					sb.append("\r\n");
					if (log.isInfoEnabled()) {
						log.info("{}, set-cookie:{}", channelContext, cookie.toString());
					}
				}
			}
		}

		sb.append("\r\n");

		byte[] headerBytes = null;
		try {
			String headerString = sb.toString();
			httpResponse.setHeaderString(headerString);
			headerBytes = headerString.getBytes(httpResponse.getCharset());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		ByteBuffer buffer = ByteBuffer.allocate(headerBytes.length + bodyLength);
		buffer.put(headerBytes);

		if (bodyLength > 0) {
			buffer.put(body);
		}
		return buffer;
	}

	/**
	 * @param args
	 *
	 * @author wchao
	 * 2017年2月22日 下午4:06:42
	 *
	 */
	public static void main(String[] args) {

	}

	/**
	 * 解析请求头的每一行
	 * @param line
	 * @return
	 *
	 * @author wchao
	 * 2017年2月23日 下午1:37:58
	 *
	 */
	public static KeyValue parseHeaderLine(String line) {
		KeyValue keyValue = new KeyValue();
		int p = line.indexOf(":");
		if (p == -1) {
			keyValue.setKey(line);
			return keyValue;
		}

		String name = line.substring(0, p).trim();
		String value = line.substring(p + 1).trim();

		keyValue.setKey(name);
		keyValue.setValue(value);

		return keyValue;
	}

	/**
	 *
	 *
	 * @author wchao
	 */
	public HttpResponseEncoder() {

	}

}
