/* 2010-03-15
 */
package com.cwasa.javacv;


import java.io.IOException;

import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;


import com.cwasa.javacv.Logging;


public class JAVideoServiceThread extends Thread {

	public static final int					VIDEO_SERVICE_PORT = 41414;
	public static final int					VIDEO_SERVICE_CHECK_PORT = VIDEO_SERVICE_PORT + 1;

	public static final String				VST_TAG = "JA Video Service Thread";

	private final Logging					LOG;

/** Writes the given message to the log. */
	//private void log(String msg)	{ System.out.println(msg); }
	private void log(String msg)	{ this.LOG.log(msg); }
/** Writes the standard prefix tag and then the given message to the log. */
	private void logt(String msg)	{ this.log(VST_TAG+msg); }

	private final ServerSocket			SERVICE_SOCKET;
	private final VideoRequestHandler		REQUEST_HANDLER;


	public JAVideoServiceThread(VideoRequestHandler vrh, Logging log)
	throws IOException {

		this.LOG = log;
		this.SERVICE_SOCKET = new ServerSocket(VIDEO_SERVICE_PORT);
		this.REQUEST_HANDLER = vrh;
	}

	public void shutDown() throws IOException { this.SERVICE_SOCKET.close(); }

	public void run() {

		this.logt(" starts.");

		try {
			while (true) {

				Socket ccsckt = this.SERVICE_SOCKET.accept();
				this.logt(": request accepted.");
				if (this.isValid(ccsckt)) {
					this.REQUEST_HANDLER.processRequest(ccsckt);
				}
			}
		}
		catch (IOException iox) { this.logt(": "+iox); }

		this.logt(" done.");
		System.out.println(VST_TAG+" done.");
	}

	private boolean isValid(Socket ccsckt) {

		boolean ok = false;
		try {
			checkLocal(ccsckt);
			ok = true;
		}
		catch (IOException iox) { this.logt(" request check fails: "+iox); }

		return ok;
	}

	public static void checkLocal(Socket ccsckt) throws IOException {

		InetAddress clientaddr = ccsckt.getInetAddress();
		InetAddress localaddr = InetAddress.getLocalHost();
		boolean ok =
			clientaddr.equals(localaddr) ||
			clientaddr.getHostAddress().equals("127.0.0.1");

		if (!ok) { throw new IOException("Non-local client: "+clientaddr); }
	}

	public static interface VideoRequestHandler {

	/** Processes one service request using the given client connection socket. */
		void processRequest(Socket ccsckt);
	}
}
