package org.academiadecodigo.enuminatti.chat;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * MIT License
 * (c) 2017 Ricardo Constantino
 */

public class ChatClient {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;
    private Scanner scanner;

    public static void main(String[] args) {

        ChatClient client = new ChatClient();

        client.connect();

        try {
            while (true) {
                client.chat();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GracefulClientQuit e) {
            System.out.println("exiting...");
        } finally {
            client.close();
        }

    }

    private void chat() throws IOException, GracefulClientQuit {

        System.out.printf("$ ");
        String outgoing = scanner.nextLine();

        out.println(outgoing);

        if (outgoing.equals("/quit") || outgoing.equals("/disconnect")) {
            throw new GracefulClientQuit();
        }

        waitForReply();
    }

    private void waitForReply() throws IOException {
        String incoming = "";
        while (incoming != null && !(incoming.equals("ACK"))) {
            System.out.println("> " + incoming);
            incoming = in.readLine();
        }
    }

    private void connect() {
        scanner = new Scanner(System.in);

        String host = getHost();
        int portNumber = getPort();

        while (!tryConnect(host, portNumber)) {
            host = getHost();
            portNumber = getPort();
        }

        try {
            out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            waitForReply();
            waitForReply();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean tryConnect(String host, int port) {
        try {
            if (host.equals(""))
                host = "127.0.0.1";

            socket = new Socket(host, port);
            return true;
        } catch (UnknownHostException e) {
            System.out.println("Unknown host.");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("Can't open socket.");
            e.printStackTrace();
        }
        return false;
    }

    private void close() {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (out != null)
            out.close();

        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private int getPort() {
        System.out.println("Listening port: ");
        return Integer.parseInt(scanner.nextLine());
    }

    private String getHost() {
        System.out.println("Server address: ");
        return scanner.nextLine();
    }

    private class GracefulClientQuit extends Exception {
    }
}
