package opc.ua.communication;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TcpThread implements Runnable {

	// server socket
	private Socket socket;
	
	/**
	 * these server I/O could be substitued with ObjectI/OStream 
	 */
	private InputStream srvInput;
	private OutputStream srvOutput;
	
	// logger
	private Logger logger;
	
	// server running?
	private  boolean listen;

	// constructor
	public TcpThread(Socket socket) {
		this.socket = socket;
		logger = Logger.getLogger(this.getClass().getName());
		logger.setLevel(Level.ALL);
		logger.addHandler((Handler)new TcpLoggerHandler());
	}
	
	/**
	 * this method is overridden from Runnable 
	 */
	public void run() {
		logger.fine("trying to run thread.");
		try {
			// create output
			srvOutput = socket.getOutputStream();
			srvOutput.flush();
			// create input
			srvInput = socket.getInputStream();			
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
			return;
		}
		logger.fine("waiting for input");
		
		// run listener for this thread
		this.listen = true;
		while (listen) {
			new ConnectionHandler(srvInput, srvOutput, this).makeTransaction();
		}
		
		// close stream pipes
		try {
			srvOutput.close();
			srvInput.close();
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}
	
	/**
	 * stop running server
	 */
	public void stop() {
		logger.fine("trying to stop thread");
		this.listen = false;
	}
	
	/**
	 * this sets logger level
	 * @param level
	 */
	public void setLoggerLevel(Level level) {
		logger.setLevel(level);
	}

}
