package sut;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.smartcardio.CardException;

public class Main implements Runnable {
	private static EMVTestService sut;
	private BufferedReader sockinLL;
	private PrintWriter sockoutLL;
	private Socket sockLL;

	@SuppressWarnings("static-access")
	public Main(EMVTestService sut, Socket sockLL, BufferedReader sockinLL, PrintWriter sockoutLL) {
		this.sut = sut;
		this.sockLL = sockLL;
		this.sockinLL = sockinLL;
		this.sockoutLL = sockoutLL;
	}

	public static void main(String[] args) {
		System.out.println("Starting Sut...");
		
		try {
			
			// port used for communication with LearnLib
			int portNo = 7892;

			// instantiate a socket for accepting a connection
			ServerSocket servsockLL = new ServerSocket(portNo);
			//servsockLL.setSoTimeout(9000000); // accept waits 5 seconds for connection
			while (true) {
				
				// wait to accept a connection request
				// then a data socket is created
				Socket sockLL = servsockLL.accept();

				// get an input stream for reading from the data socket
				InputStream inStreamLL = sockLL.getInputStream();
				// create a BufferedReader object for text line input
				BufferedReader sockinLL = new BufferedReader(
						new InputStreamReader(inStreamLL));

				// get an output stream for writing to the data socket
				OutputStream outStreamLL = sockLL.getOutputStream();
				// create a PrinterWriter object for character-mode output
				PrintWriter sockoutLL = new PrintWriter(new OutputStreamWriter(
						outStreamLL));

				System.out.println("New client...");
				sut = EMVTestService.createEMVTestService();
				Main client = new Main(sut, sockLL, sockinLL, sockoutLL);
				new Thread(client).start();
			}
		}
		catch (CardException cex) {
			System.out.println("CardException in main ...");
			cex.printStackTrace();	
		}
		catch (IOException e) {
			System.out.println("IOException in main ...");
			e.printStackTrace();
		}
		System.out.println("Closing Sut client starter...");
	}

	public void run() {
		System.out.println("Starting client...");
		try {
			String input;
			while ((input = sockinLL.readLine()) != null) {

				//System.out.println("Handling: " + input);
				System.out.println("input");
				if (input.equals("reset")) {
					System.out.println("SUT Main receiving: reset");
					
					sut.reset();
					
					//sut = EMVTestService.createEMVTestService();
					//Main client = new Main(sut, sockLL, sockinLL, sockoutLL);
					//new Thread(client).start();
					
					System.out.println("reset done");
					continue;
				}
				else if (input.equals("getATC")){
					System.out.println("SUT Main receiving: getATC");

					sockoutLL.println(sut.getATC());
					sockoutLL.flush();
					
					continue;
				}
				/*else if (input.equals("connect")) {
					System.out.println("SUT Main receiving: connect");
					
					sut.connect();
					System.out.println("connect done");
					continue;
				}*/
				
				System.out.println("process");
				
				String result = sut.processSymbol(input);
				System.out.println("Returning: " + result.substring(4));
				/*if(result.substring(4, 8).equals("9000")) {
					System.out.println("9000");
					result = "OK";
				}
				else {
					System.out.println("NOT 9000");
					result = "NOK";
				}*/
					
				//System.out.println("Returning: " + result.toString());

				// send output to LearnLib
				System.out.println("return output");
				sockoutLL.println(result.substring(4));
				sockoutLL.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("reset...");
		} catch (CardException cex) {
			// TODO Auto-generated catch block
			cex.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		try {
			sockinLL.close();
			sockoutLL.close();
			sockLL.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		System.out.println("Closing client...");
	}
}
