/*******************************************************************************
 * Copyright (c) 2003, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.internet.monitor.core.internal.http;

import java.io.*;
import org.eclipse.wst.internet.monitor.core.internal.Connection;
import org.eclipse.wst.internet.monitor.core.internal.Trace;
import org.eclipse.wst.internet.monitor.core.internal.provisional.Request;
/**
 * Monitor server I/O thread.
 */
public class HTTPThread extends Thread {
	private static final int BUFFER = 2048;
	private static final byte CR = (byte) '\r';
	private static final byte LF = (byte) '\n';
	protected static int threadCount = 0;

	private byte[] readBuffer = new byte[BUFFER];

	// buffer and index
	protected byte[] buffer = new byte[0];
	protected int bufferIndex = 0;

	protected InputStream in;
	protected OutputStream out;
	protected HTTPConnection conn;
	protected boolean isRequest;
	protected Connection conn2;
	
	protected HTTPThread request;
	protected boolean isWaiting;
	
	// user to translate the Host: header
	protected String host;
	protected int port;

	protected int contentLength = -1;
	protected byte transferEncoding = -1;
	protected String responseType = null;
	protected boolean keepAlive = false;

	protected static final String[] ENCODING_STRING = new String[] {
		"chunked", "identity", "gzip", "compressed", "deflate"};

	protected static final byte ENCODING_CHUNKED = 0;
	protected static final byte ENCODING_IDENTITY = 1;
	protected static final byte ENCODING_GZIP = 2;
	protected static final byte ENCODING_COMPRESSED = 3;
	protected static final byte ENCODING_DEFLATE = 4;

/* change:
Referer: http://localhost:8081/index.html
Host: localhost:8081
*/
/* The Connection header has the following grammar:

	   Connection = "Connection" ":" 1#(connection-token)
	   connection-token  = token

   HTTP/1.1 proxies MUST parse the Connection header field before a
   message is forwarded and, for each connection-token in this field,
   remove any header field(s) from the message with the same name as the
   connection-token. */

	/**
	 * Create a new HTTP thread.
	 * 
	 * @param conn2
	 * @param in
	 * @param out
	 * @param conn
	 * @param isRequest
	 * @param host
	 * @param port
	 */
	public HTTPThread(Connection conn2, InputStream in, OutputStream out, HTTPConnection conn, boolean isRequest, String host, int port) {
		super();
		this.conn2 = conn2;
		this.in = in;
		this.out = out;
		this.conn = conn;
		this.isRequest = isRequest;
		this.host = host;
		this.port = port;
	
		setName("HTTP (" + host + ":" + port + ") " + (isRequest ? "REQUEST" : "RESPONSE") + " " + (threadCount++));
		setPriority(Thread.NORM_PRIORITY + 1);
		setDaemon(true);
		
		Trace.trace(Trace.PARSING, "Started: " + this);
	}
	
	/**
	 * Create a new HTTP thread.
	 * 
	 * @param conn2
	 * @param in
	 * @param out
	 * @param conn
	 * @param isRequest
	 * @param host
	 * @param port
	 * @param request
	 */
	public HTTPThread(Connection conn2, InputStream in, OutputStream out, HTTPConnection conn, boolean isRequest, String host, int port, HTTPThread request) {
		this(conn2, in, out, conn, isRequest, host, port);
		
		this.request = request;
	}

	/**
	 * Add a line feed to the end of the byte array.
	 * @return byte[]
	 * @param b byte[]
	 */
	protected static byte[] convert(byte[] b) {
		if (b == null || b.length == 0)
			return b;
	
		int size = b.length;
		byte[] x = new byte[size + 2];
		System.arraycopy(b, 0, x, 0, size);
		x[size] = (byte) '\r';     // CR
		x[size + 1] = (byte) '\n'; // LF
		return x;
	}

	/**
	 * Read more data into the buffer.
	 */
	protected void fillBuffer() throws IOException {
		int n = in.read(readBuffer);
	
		if (n <= 0)
			throw new IOException("End of input");
	
		// add to full buffer
		int len = buffer.length - bufferIndex;
		if (len < 0)
			len = 0;
		byte[] x = new byte[n + len];
		System.arraycopy(buffer, bufferIndex, x, 0, len);
		System.arraycopy(readBuffer, 0, x, len, n);
		bufferIndex = 0;
		buffer = x;
	}

	/**
	 * Returns the first location of a CRLF.
	 *
	 * @return int
	 */
	protected int getFirstCRLF() {
		int size = buffer.length;
		int i = bufferIndex + 1;
		while (i < size) {
			if (buffer[i - 1] == CR && buffer[i] == LF)
				return i;
			i++;
		}
		return -1;
	}

	/**
	 * Output the given bytes.
	 * @param b byte[]
	 */
	protected void outputBytes(byte[] b, boolean isNew) throws IOException {
		out.write(b);
		if (isRequest)
			conn.addRequest(b, isNew);
		else
			conn.addResponse(b, isNew);
	}

	/**
	 * Parse the HTTP body.
	 * 
	 * @throws IOException
	 */
	public void parseBody() throws IOException {
		Trace.trace(Trace.PARSING, "Parsing body for: " + this);
		
		if (isRequest) {
			if (contentLength != -1) {
				byte[] b = readBytes(contentLength);
				out.write(b);
				conn.addRequest(b, false);
				setHTTPBody(b);
			} else if (transferEncoding != -1 && transferEncoding != ENCODING_IDENTITY) {
				parseChunk();
			}
			
			Trace.trace(Trace.PARSING, "Done parsing request body for: " + this);
			return;
		}
	
		// just return body for HTTP 1.0 responses
		if (!isRequest && !keepAlive && contentLength == -1 && transferEncoding == -1) {
			Trace.trace(Trace.PARSING, "Assuming HTTP 1.0 for: " + this);
			int n = buffer.length - bufferIndex;
			byte[] b = readBytes(n);
			byte[] body = new byte[0];
			while (n >= 0) {
				Trace.trace(Trace.PARSING, "Bytes read: " + n + " " + this);
				if (b != null && n > 0) {
					byte[] x = null;
					if (n == b.length)
						x = b;
					else {
						x = new byte[n];
						System.arraycopy(b, 0, x, 0, n);
					}
					outputBytes(x, false);
					
					// copy to HTTP body
					byte[] temp = new byte[body.length + x.length];
					System.arraycopy(body, 0, temp, 0, body.length);
					System.arraycopy(x, 0, temp, body.length, x.length);
					body = temp;
				}
				if (b.length < BUFFER)
					b = new byte[BUFFER];
				n = in.read(b);
				Thread.yield();
			}
			out.flush();
			setHTTPBody(body);
			return;
		}
	
		// spec 4.4.1
		if (responseType != null &&	(responseType.startsWith("1") || "204".equals(responseType) || "304".equals(responseType))) {
			setHTTPBody(new byte[0]);
			return;
		}
	
		// spec 4.4.2
		if (transferEncoding != -1 && transferEncoding != ENCODING_IDENTITY) {
			parseChunk();
			return;
		}
	
		// spec 4.4.3
		if (contentLength != -1) {
			byte[] b = readBytes(contentLength);
			out.write(b);
			if (isRequest)
				conn.addRequest(b, false);
			else
				conn.addResponse(b, false);
			setHTTPBody(b);
			return;
		}
		
		// spec 4.4.4 (?)
		
		Trace.trace(Trace.PARSING, "Unknown body for: " + this);
	}

	/**
	 * Parse an HTTP chunk.
	 * 
	 * @throws IOException
	 */
	public void parseChunk() throws IOException {
		Trace.trace(Trace.PARSING, "Parsing chunk for: " + this);
		boolean done = false;
		byte[] body = new byte[0];
	
		while (!done) {
			// read chunk size
			byte[] b = readLine();
	
			String s = new String(b);
			int index = s.indexOf(" ");
			int length = -1;
			try {
				if (index > 0)
					s = s.substring(0, index);
				length = Integer.parseInt(s.trim(), 16);
			} catch (Exception e) {
				Trace.trace(Trace.PARSING, "Error chunk for: " + this, e);
			}
	
			// output bytes
			outputBytes(b, false);
	
			if (length <= 0)
				done = true;
			else {
				// read and output chunk data plus CRLF
				b = readBytes(length + 2);
				outputBytes(b, false);
				
				// copy to HTTP body
				byte[] temp = new byte[body.length + b.length - 2];
				System.arraycopy(body, 0, temp, 0, body.length);
				System.arraycopy(b, 0, temp, body.length, b.length - 2);
				body = temp;
			}
		}
	
		// read trailer
		byte[] b = readLine();
		while (b.length > 2) {
			outputBytes(b, false);
			b = readLine();
		}
	
		outputBytes(b, false);
		setHTTPBody(body);
	}

	/**
	 * Parse an HTTP header.
	 * 
	 * @throws IOException
	 */
	public void parseHeader() throws IOException {
		Trace.trace(Trace.PARSING, "Parsing header for: " + this);
	
		// read until first blank line
		boolean isFirstLine = true;
		boolean isNew = true;
	
		byte[] b = readLine();
		while (b.length > 5) {
			Trace.trace(Trace.PARSING, "Parsing header line: '" + new String(b) + "'");
			
			if (isFirstLine) {
				String s = new String(b);
				if (isRequest) {
					setLabel(s);
					isNew = false;
				}
	
				if (!isRequest) {
					int index1 = s.indexOf(' ');
					int index2 = s.indexOf(' ', index1 + 1);
	
					try {
						responseType = s.substring(index1 + 1, index2).trim();
						Trace.trace(Trace.PARSING, "Response Type: " + this + " " + responseType);
					} catch (Exception e) {
						Trace.trace(Trace.PARSING, "Error parsing response type for: " + this, e);
					}
					if (responseType != null && responseType.equals("100")) {
						outputBytes(b, isNew);
						isNew = false;

						b = readLine();
						outputBytes(b, false);

						b = readLine();

						index1 = s.indexOf(' ');
						index2 = s.indexOf(' ', index1 + 1);

						try {
							responseType = s.substring(index1 + 1, index2).trim();
							Trace.trace(Trace.PARSING, "Response Type: " + this + " " + responseType);
						} catch (Exception e) {
							Trace.trace(Trace.PARSING, "Error parsing response type for: " + this, e);
						}
					}
				}
				isFirstLine = false;
			}
	
			// translate
			b = translateHeaderLine(b);
			
			outputBytes(b, isNew);
			isNew = false;
	
			b = readLine();
		}

		Trace.trace(Trace.PARSING, "Parsing final header line: '" + new String(b) + "'");

		outputBytes(b, false);

		Request rr = conn.getRequestResponse(isRequest);
		Trace.trace(Trace.PARSING, "Setting header length: " + rr.getRequest(Request.ALL).length);
		
		setHTTPHeader(rr);
	}

	/**
	 * Read bytes from the stream.
	 * @return byte[]
	 */
	protected byte[] readBytes(int n) throws IOException {
		Trace.trace(Trace.PARSING, "readBytes() " + n + " for: " + this);
		while (buffer.length - bufferIndex < n)
			fillBuffer();
	
		return removeFromBuffer(bufferIndex + n);
	}

	/**
	 * Read and return the next full line.
	 *
	 * @return byte[]
	 */
	protected byte[] readLine() throws IOException {
		Trace.trace(Trace.PARSING, "readLine() for: " + this);
	
		int n = getFirstCRLF();
		while (n < 0) {
			fillBuffer();
			n = getFirstCRLF();
		}
		return removeFromBuffer(n + 1);
	}

	/**
	 * Remove data from the buffer up to the absolute index n.
	 * Return the data from between bufferIndex and n.
	 *
	 * @param n the bytes to remove
	 * @return a byte array
	 */
	protected byte[] removeFromBuffer(int n) {
		// copy line out of buffer
		byte[] b = new byte[n - bufferIndex];
		System.arraycopy(buffer, bufferIndex, b, 0, n - bufferIndex);
	
		if (buffer.length > BUFFER * 2 || bufferIndex > BUFFER) {
			// remove line from buffer
			int size = buffer.length;
			byte[] x = new byte[size - n];
			System.arraycopy(buffer, n, x, 0, size - n);
			buffer = x;
			bufferIndex = 0;
		} else
			bufferIndex = n;
	
		return b;
	}

	/**
	 * Listen for input, save it, and pass to the output stream.
	 * Philosophy: Read a single line separately and translate.
	 * When blank line is reached, just pass all other data through.
	 */
	public void run() {
		try {
			try {
				while (true) {
					contentLength = -1;
					transferEncoding = -1;
					keepAlive = false;

					parseHeader();
					parseBody();
					
					if (isRequest && keepAlive)
						waitForResponse();
					
					//Request r = conn.getRequestResponse(true);
					//r.fireChangedEvent();

					Trace.trace(Trace.PARSING, "Done HTTP request for " + this + " " + keepAlive);
					if (!isRequest && !request.keepAlive) {
						conn2.close();
						break;
					}
					
					if (!isRequest)
						notifyRequest();
					
					Thread.yield();
				}
			} catch (IOException e) {
				// reached end of input
				Trace.trace(Trace.PARSING, "End of buffer for: " + this + " " + e.getMessage());
			}

			// send rest of buffer
			out.write(buffer, bufferIndex, buffer.length - bufferIndex);
			out.flush();
		} catch (Exception e) {
			Trace.trace(Trace.PARSING, "Error in: " + this, e);
		}
		//if (!isRequest)
		//	conn2.close();

		Trace.trace(Trace.PARSING, "Closing thread " + this);
	}

	/**
	 * Sets the title of the call.
	 *
	 * @param s java.lang.String
	 */
	protected void setLabel(String s) {
		try {
			int index1 = s.indexOf(' ');
			if (index1 < 0 || index1 > 15)
				return;
			int index2 = s.indexOf(' ', index1 + 1);
			if (index2 < 0)
				return;
	
			conn.setLabel(s.substring(index1 + 1, index2), true);
		} catch (Exception e) {
			// ignore
		}
	}

	/**
	 * Translate the header line.
	 * 
	 * @return byte[]
	 * @param b byte[]
	 */
	protected byte[] translateHeaderLine(byte[] b) {
		String s = new String(b);
	
		if (isRequest && s.startsWith("Host: ")) {
			String t = "Host: " + host;
			if (port != 80)
				t += ":" + port;
			return convert(t.getBytes());
		} else if (s.startsWith("Content-Length: ")) {
			try {
				contentLength = Integer.parseInt(s.substring(16).trim());
				Trace.trace(Trace.PARSING, "Content length: " + this + " " + contentLength);
			} catch (Exception e) {
				Trace.trace(Trace.PARSING, "Content length error", e);
			}
		} else if (s.startsWith("Connection: ")) {
			try {
				String t = s.substring(11).trim();
				if (t.equalsIgnoreCase("Keep-Alive"))
					keepAlive = true;
				Trace.trace(Trace.PARSING, "Keep alive: " + keepAlive);
			} catch (Exception e) {
				Trace.trace(Trace.PARSING, "Error getting Connection: from header", e);
			}
		} else if (s.startsWith("Transfer-Encoding: ")) {
			String t = s.substring(19).trim();
			int size = ENCODING_STRING.length;
			for (int i = 0; i < size; i++) {
				if (ENCODING_STRING[i].equalsIgnoreCase(t)) {
					transferEncoding = (byte) i;
					Trace.trace(Trace.PARSING, "Transfer encoding: " + ENCODING_STRING[i]);
				}
			}
		}
	
		return b;
	}
	
	protected void close() {
		try {
			Trace.trace(Trace.PARSING, "Closing: " + this);
			out.close();
		} catch (Exception e) {
			Trace.trace(Trace.PARSING, "Error closing connection " + this + " " + e.getMessage());
		}
	}

	protected void waitForResponse() {
		Trace.trace(Trace.PARSING, "Waiting for response " + this);
		synchronized (this) {
			try {
				isWaiting = true;
				wait();
			} catch (Exception e) {
				Trace.trace(Trace.PARSING, "Error in waitForResponse() " + this + " " + e.getMessage());
			}
			isWaiting = false;
		}
		Trace.trace(Trace.PARSING, "Done waiting for response " + this);
	}

	protected void notifyRequest() {
		Trace.trace(Trace.PARSING, "Notifying request " + this);
		while (request.keepAlive && !request.isWaiting) {
			Trace.trace(Trace.PARSING, "Waiting for request " + this);
			try {
				Thread.sleep(100);
			} catch (Exception e) {
				// ignore
			}
		}
		synchronized (request) {
			try {
				request.notify();
			} catch (Exception e) {
				Trace.trace(Trace.PARSING, "Error in notifyRequest() " + this + " " + e.getMessage());
			}
		}
		Trace.trace(Trace.PARSING, "Done notifying request " + this);
	}
	
	protected void setHTTPHeader(Request rr) {
		if (isRequest) {
			byte[] b = rr.getRequest(Request.ALL);
			byte[] h = new byte[b.length];
			System.arraycopy(b, 0, h, 0, b.length);
			rr.setProperty(HTTPRequest.HTTP_REQUEST_HEADER, h);
		} else {
			byte[] b = rr.getResponse(Request.ALL);
			byte[] h = new byte[b.length];
			System.arraycopy(b, 0, h, 0, b.length);
			rr.setProperty(HTTPRequest.HTTP_RESPONSE_HEADER, h);
		}
	}
	
	protected void setHTTPBody(byte[] b) {
		Request rr = conn.getRequestResponse(isRequest);
		if (isRequest)
			rr.setProperty(HTTPRequest.HTTP_REQUEST_BODY, b);
		else
			rr.setProperty(HTTPRequest.HTTP_RESPONSE_BODY, b);
	}
}