package com.eactive.eai.adapter.socket2.protocol.http.codec;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.demux.MessageEncoder;
import org.apache.mina.util.CharsetUtil;

import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

public class HttpResponseEncoder implements MessageEncoder {
	private static final Set<Class<?>> TYPES;

	static {
		Set<Class<?>> types = new HashSet<Class<?>>();
		types.add(HttpResponse.class);
		TYPES = Collections.unmodifiableSet(types);
	}

	private static final byte[] CRLF = new byte[] { 0x0D, 0x0A };

	public HttpResponseEncoder() {
	}

	public void encode(IoSession session, Object message, ProtocolEncoderOutput out)
			throws Exception {
		HttpResponse msg = (HttpResponse) message;
		ByteBuffer buf = ByteBuffer.allocate(256);
		// Enable auto-expand for easier encoding
		buf.setAutoExpand(true);

		try {
			// output all headers except the content length
			//CharsetEncoder encoder = Charset.defaultCharset().newEncoder();
			CharsetEncoder encoder = CharsetUtil.getDefaultCharset().newEncoder();
			buf.putString("HTTP/1.1 ", encoder);
			buf.putString(String.valueOf(msg.getResponseCode()), encoder);
			switch (msg.getResponseCode()) {
			case HttpResponse.HTTP_STATUS_SUCCESS:
				buf.putString(" OK", encoder);
				break;
			case HttpResponse.HTTP_STATUS_NOT_FOUND:
				buf.putString(" Not Found", encoder);
				break;
			}
			buf.put(CRLF);
			for (Iterator it = msg.getHeaders().entrySet().iterator(); it.hasNext();) {
				Entry entry = (Entry) it.next();
				buf.putString((String) entry.getKey(), encoder);
				buf.putString(": ", encoder);
				buf.putString((String) entry.getValue(), encoder);
				buf.put(CRLF);
			}
			// now the content length is the body length
			buf.putString("Content-Length: ", encoder);
			buf.putString(String.valueOf(msg.getBodyLength()), encoder);
			buf.put(CRLF);
			buf.put(CRLF);
			// add body
			buf.put(msg.getBody());
		} catch (CharacterCodingException ex) {
			out.flush();
		}

		buf.flip();
		out.write(buf);
	}

	public Set<Class<?>> getMessageTypes() {
		return TYPES;
	}
}
