package server;

import help.ServerInfo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

//import ;

public class Main {
	protected static final Logger log = Logger.getLogger(server.Main.class.getName());
	private static int verbose = 0;
	public static void main(String []args) {
		
		long maxClients = help.Default.SERVER_INFO.getMaxClients();
		int serverPort = help.Default.SERVER_INFO.getPort();
		for (int i = 0; i < args.length; i += 2) {
			if (args[i].equals("-c") || args[i].equals("--max-client"))
				maxClients = Long.parseLong(args[i + 1]);
			else if (args[i].equals("-p") || args[i].equals("--port"))
				serverPort = Integer.parseInt(args[i + 1]);
			else if (args[i].equals("-q") || args[i].equals("--quiet")) {
				verbose = 0;
			}
			else if (args[i].equals("-v") || args[i].equals("--verbose")) {
				verbose = 1;
			}
		}
		
		initializeLogger();

		ServerInfo serverInfo = new ServerInfo("localhost", serverPort, maxClients);

		log.info("Server MAIN start");
		
		manageInputCommandForServer(serverInfo);

		System.out.println("Server end");

		log.info("Server MAIN end");
	}
	
	/**
	 * manage command for server, received from command line
	 * @param max_client 
	 * @param serverPort 
	 */
	protected static void manageInputCommandForServer(ServerInfo serverInfo) {
		BufferedReader commandReader = new BufferedReader(new InputStreamReader(System.in));
		log.info("CREATE BufferedReader");
		
		Thread chatServerThread = null;
		String commandLine = null;
		// manage server commands
		while (true) {
			System.out.print("command: ");
			commandLine = readInputCommadForServer(commandReader);
			if (commandLine.startsWith(ServerCommand.START.getName())) {
				chatServerThread = startChatServer(chatServerThread, serverInfo);
			} else if (commandLine.startsWith(ServerCommand.EXIT.getName())) {
				if (chatServerThread != null)
					stopChatServer(chatServerThread);
				log.info("Break command loop");
				break;
			} else {// TODO stop, change port ... command 
				log.info("unsupported, incorrect or not well formed command: " + commandLine);
				System.out.println("unsupported, incorrect or not well formed command");				
			}
		}
	}

	/**
	 * @param chatServerThread
	 */
	protected static void stopChatServer(Thread chatServerThread) {
		while (chatServerThread.isAlive()) {
			chatServerThread.interrupt();
			log.info("INTERRUPT chat Server Thread");
			try {
				// this dummyClient is needed when chatServerThread
				// is blocked in serverSocket.accept();
				Socket dummyClient = new Socket (help.Default.SERVER_INFO.getIpAddress(),help.Default.SERVER_INFO.getPort());
				log.info("CREATE dummy socket");
				dummyClient.close();
				log.info("CLOSE dummy socket");
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				log.info("Receive UnknownHostException");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				log.info("Receive IOException");
			}
			try {
				log.info("JOIN chat Server Thread");
				chatServerThread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
				log.info("Server Main thread is interrupted when stoping serever chat thread");
			}
		}
		log.info("Server Main thread stop chat server thread");		
	}

	/**
	 * start chat server if is not started
	 * 					 else inform that the server is started
	 * 
	 * @param chatServerThread
	 * @return
	 */
	protected static Thread startChatServer(Thread chatServerThread, ServerInfo serverInfo) {
		if (chatServerThread == null) {
			ChatServer chatServer = new ChatServer(serverInfo, verbose);
			log.info("CREATE chat server object");
			chatServerThread = new Thread(chatServer);
			log.info("CREATE thread for chat server object");
			chatServerThread.start();
			log.info("Start thread for chat server object");
		}
		else {
			System.out.println("chat sever is already started");
			log.info("chat sever is already started");
		}
		return chatServerThread;
	}
	/**
	 * @param commandReader
	 * @param commandLine
	 * @return
	 */
	protected static String readInputCommadForServer(BufferedReader commandReader) {
		String commandLine = null;
		do {
			try {
				commandLine = commandReader.readLine();
				log.info("receive command: " + commandLine);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				commandLine = null;
				log.info("receive command: FAIL");
			}
		} while (commandLine == null);
		return commandLine;
	}
	/**
	 * 
	 */
	protected static void initializeLogger() {
		try {
			FileHandler fh = new FileHandler(server.Main.class.getName()+".log");
			fh.setFormatter(new SimpleFormatter());
			log.addHandler(fh);
		} catch (SecurityException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			System.exit(-1);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			System.exit(-2);
		}
		log.setUseParentHandlers(verbose != 0);
		log.setLevel(Level.ALL);
	}
}
