/*******************************************************************************
 * Copyright (c) 2003, 2008 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;

import java.io.InterruptedIOException;
import java.net.*;

import org.eclipse.wst.internet.monitor.core.internal.provisional.IMonitor;
/**
 * The actual TCP/IP monitoring server. This is a thread that
 * listens on a port and relays a call to another server.
 */
public class AcceptThread {
	protected IMonitor monitor;

	protected boolean alive = true;
	protected ServerSocket serverSocket;

	protected Thread thread;

	class ServerThread extends Thread {
		public ServerThread() {
			super("TCP/IP Monitor");
		}

		/**
		 * ServerThread accepts incoming connections and delegates to the protocol
		 * adapter to deal with the connection.
		 */
		public void run() {
			// create a new server socket
			try {
				serverSocket = new ServerSocket(monitor.getLocalPort());
				serverSocket.setSoTimeout(2000);
				Trace.trace(Trace.FINEST, "Monitoring localhost:" + monitor.getLocalPort() + " -> " + monitor.getRemoteHost()
						+ ":" + monitor.getRemotePort());
			} catch (Exception e) {
				Trace.trace(Trace.SEVERE, "Could not start monitoring");
				return;
			}
			
			while (alive) {
				try {
					// accept the connection from the client
					Socket localSocket = serverSocket.accept();
					
					int timeout = monitor.getTimeout();
					if (timeout != 0)
						localSocket.setSoTimeout(timeout);
					
					try {
						// connect to the remote server
						Socket remoteSocket = new Socket();
						if (timeout != 0)
							remoteSocket.setSoTimeout(timeout);
						
						remoteSocket.connect(new InetSocketAddress(monitor.getRemoteHost(), monitor.getRemotePort()), timeout);
						
						// relay the call through
						String protocolId = monitor.getProtocol();
						ProtocolAdapter adapter = MonitorPlugin.getInstance().getProtocolAdapter(protocolId);
						adapter.connect(monitor, localSocket, remoteSocket);
					} catch (SocketTimeoutException e) {
						FailedConnectionThread thread2 = new FailedConnectionThread((Monitor) monitor, localSocket, Messages.errorConnectTimeout);
						thread2.start();
					} catch (Exception e) {
						FailedConnectionThread thread2 = new FailedConnectionThread((Monitor) monitor, localSocket, null);
						thread2.start();
					}
				} catch (InterruptedIOException e) {
					// do nothing
				} catch (Exception e) {
					if (alive)
						Trace.trace(Trace.SEVERE, "Error while monitoring", e);
				}
			}
		}
	}

	/**
	 * AcceptThread constructor.
	 * 
	 * @param monitor a monitor
	 */
	public AcceptThread(IMonitor monitor) {
		super();
		this.monitor = monitor;
	}
	
	/**
	 * Start the server.
	 */
	public void startServer() {
		if (thread != null)
			return;
		thread = new ServerThread();
		thread.setDaemon(true);
		thread.setPriority(Thread.NORM_PRIORITY + 1);
		thread.start();
		
		Thread.yield();
		
		// wait up to 2 seconds for initialization
		int i = 0;
		while (serverSocket == null && i < 10) {
			try {
				Thread.sleep(200);
			} catch (Exception e) {
				// ignore
			}
			i++;
		}
	}

	/**
	 * Returns <code>true</code> if the server is running.
	 * 
	 * @return <code>true</code> if the server is running, and <code>false</code>
	 *    otherwise
	 */
	public boolean isRunning() {
		return (thread != null);
	}

	/**
	 * Correctly close the server socket and shut down the server.
	 */
	public void stopServer() {
		try {
			alive = false;
			thread = null;
			
			String protocolId = monitor.getProtocol();
		   ProtocolAdapter adapter = MonitorPlugin.getInstance().getProtocolAdapter(protocolId);
			adapter.disconnect(monitor);
			if (serverSocket != null)
				serverSocket.close();
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error stopping server", e);
		}
	}
	
	/**
	 * Returns true if this port is in use.
	 *
	 * @return boolean
	 * @param port int
	 */
	public static boolean isPortInUse(int port) {
		ServerSocket s = null;
		try {
			s = new ServerSocket(port);
		} catch (SocketException e) {
			return true;
		} catch (Exception e) {
			return true;
		} finally {
			if (s != null) {
				try {
					s.close();
				} catch (Exception e) {
					// ignore
				}
			}
		}

		return false;
	}
}
