package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * A console client for the chat server: prints every line the server sends, and
 * sends every line typed at the keyboard. Two threads, because the server may
 * send at any time, not only in reply. The main thread reads from the server. A
 * daemon thread reads the keyboard and sends, so when the server closes the
 * connection, main finishes and the program ends. Arguments: host and port
 * (default localhost 6000, the chat server).
 */
public class ChatClient {

	public static void main ( String[] args ) {
		String host = "localhost";
		int port = ChatServer.PORT;
		if ( args.length >= 2 ) {
			host = args[0];
			port = Integer.parseInt(args[1]);
		}

		try {
			Socket socket = new Socket(host,port);
			BufferedReader in =
			    new BufferedReader(new InputStreamReader(socket.getInputStream(),
			                                             StandardCharsets.UTF_8));
			PrintWriter out =
			    new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),
			                                           StandardCharsets.UTF_8));

			Thread typing = new Thread(new KeyboardSender(socket,out),"keyboard");
			typing.setDaemon(true);
			typing.start();

			for ( ; true ; ) {
				String line = in.readLine(); // blocks until the server sends something
				if ( line == null ) {
					System.out.println("[connection closed]");
					break;
				}
				System.out.println(line);
			}
			socket.close();
		} catch ( IOException e ) {
			System.out.println("can't talk to " + host + ":" + port + ": "
			    + e.getMessage());
		}
	}

	/**
	 * Sends each line typed at the keyboard. The only thread that writes to the
	 * socket.
	 */
	private static class KeyboardSender implements Runnable {

		private Socket socket_;
		private PrintWriter out_;

		public KeyboardSender ( Socket socket, PrintWriter out ) {
			socket_ = socket;
			out_ = out;
		}

		@Override
		public void run () {
			Scanner keyboard = new Scanner(System.in);
			for ( ; keyboard.hasNextLine() ; ) {
				out_.println(keyboard.nextLine());
				out_.flush();
			}
			try {
				socket_.shutdownOutput(); // end of typing: tell the server we're done
			} catch ( IOException e ) {}
		}

	}

}
