/*Не проходит валидацию по пункту 5. Метод clientMainLoop должен принимать сообщения от сервера до тех пор, пока тип сообщения равен MessageType.TEXT, MessageType.USER_REMOVED или MessageType.USER_ADDED.*/

package com.javarush.task.task30.task3008.client;

import com.javarush.task.task30.task3008.Connection;
import com.javarush.task.task30.task3008.ConsoleHelper;
import com.javarush.task.task30.task3008.Message;
import com.javarush.task.task30.task3008.MessageType;

import java.io.IOException;

/*** Created by User on 17.09.17.*/
public class Client {
    protected Connection connection;
    private volatile boolean clientConnected = false;

    protected String getServerAddress() {
        ConsoleHelper.writeMessage("Введите ip-адрес или localhost.");
        return ConsoleHelper.readString();
    }

    protected int getServerPort() {
        ConsoleHelper.writeMessage("Введите № порта сервера.");
        return ConsoleHelper.readInt();
    }

    protected String getUserName() {
        ConsoleHelper.writeMessage("Введите Ваше имя.");
        return ConsoleHelper.readString();
    }

    protected boolean shouldSendTextFromConsole() {
        return true;
    }

    protected SocketThread getSocketThread() {
        return new SocketThread();
    }

    protected void sendTextMessage(String text) {
        try {
            connection.send(new Message(MessageType.TEXT, text));
        } catch (IOException e) {
            ConsoleHelper.writeMessage(e.getMessage());
            clientConnected = false;
        }
    }

    public void run() {
        SocketThread socketThread = getSocketThread();
        socketThread.setDaemon(true);
        socketThread.start();
        synchronized (this) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                ConsoleHelper.writeMessage(e.getMessage());
                return;
            }
        }
        if (clientConnected) {
            ConsoleHelper.writeMessage("Соединение установлено. Для выхода наберите команду ‘exit’.");
            while (clientConnected) {
                String text = ConsoleHelper.readString();
                if (text.equals("exit")) {
                    clientConnected = false;
                } else {
                    if (shouldSendTextFromConsole()) sendTextMessage(text);
                }
            }
        } else {
            ConsoleHelper.writeMessage("Произошла ошибка во время работы клиента.");
        }
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.run();
    }

    public class SocketThread extends Thread {
        protected void processIncomingMessage(String message) {
            ConsoleHelper.writeMessage(message);
        }

        protected void informAboutAddingNewUser(String userName) {
            ConsoleHelper.writeMessage(userName.concat(" теперь с нами!"));
        }

        protected void informAboutDeletingNewUser(String userName) {
            ConsoleHelper.writeMessage(userName.concat(" безвременно покинул чат. Помним. Скорбим."));
        }

        protected void notifyConnectionStatusChanged(boolean clientConnected) {
            Client.this.clientConnected = clientConnected;
            synchronized (Client.this) {
                Client.this.notify();
            }
        }

        protected void clientHandshake() throws IOException, ClassNotFoundException {
            Message message;
            while (true) {
                try {
                    message = connection.receive();
                } catch (Exception e) {
                    break;
                }
                if (message != null) {
                    if (message.getType() == MessageType.NAME_REQUEST) {
                        connection.send(new Message(MessageType.USER_NAME, getUserName()));
                    } else {
                        if (message.getType() == MessageType.NAME_ACCEPTED) {
                            notifyConnectionStatusChanged(true);
                            return;
                        } else {
                            throw new IOException("Unexpected MessageType");
                        }
                    }
                }
            }
        }

        protected void clientMainLoop() throws IOException, ClassNotFoundException {
            Message message;
            while (true) {
                try {
                    message = connection.receive();
                } catch (Exception e) {
                    break;
                }
                if (message != null) {
                    if (message.getType() == MessageType.TEXT) {
                        processIncomingMessage(message.getData());
                    } else {
                        if (message.getType() == MessageType.USER_ADDED) {
                            informAboutAddingNewUser(message.getData());
                        } else {
                            if (message.getType() == MessageType.USER_REMOVED) {
                                informAboutDeletingNewUser(message.getData());
                            } else {
                                break;
                            }
                        }
                    }
                }
            }
            throw new IOException("Unexpected MessageType");
        }

//        protected void clientMainLoop() throws IOException, ClassNotFoundException {
//            Message message;
//            try {
//                while (true) {
//                    try {
//                        message = connection.receive();
//                    } catch (Exception e) {
//                        break;
//                    }
//                    if (message != null) {
//                        switch (message.getType()) {
//                            case TEXT:
//                                processIncomingMessage(message.getData());
//                                break;
//                            case USER_ADDED:
//                                informAboutAddingNewUser(message.getData());
//                                break;
//                            case USER_REMOVED:
//                                informAboutDeletingNewUser(message.getData());
//                                break;
//                            default:
//                                throw new IOException("Unexpected MessageType");
//                        }
//                    }
//                }
//            }catch (Exception e){throw new IOException("Unexpected MessageType");}
//        }

//        protected void clientMainLoop() throws IOException, ClassNotFoundException {
//            Message message;
//            do {
//                try {
//                    message = connection.receive();
//                }catch (Exception e) {break;}
//                if (message != null) {
//                    if (message.getType() == MessageType.TEXT) {
//                        processIncomingMessage(message.getData());
//                    } else {
//                        if (message.getType() == MessageType.USER_ADDED) {
//                            informAboutAddingNewUser(message.getData());
//                        } else {
//                            if (message.getType() == MessageType.USER_REMOVED) {
//                                informAboutDeletingNewUser(message.getData());
//                            } else {
//                                if (message.getType() != MessageType.TEXT
//                                        && message.getType() != MessageType.USER_ADDED
//                                        && message.getType() != MessageType.USER_REMOVED)
//                                    break;
//                            }
//                        }
//                    }
//                }
//            } while (true);
//            throw new IOException("Unexpected MessageType");
//        }

//        protected void clientMainLoop() throws IOException, ClassNotFoundException {
//            Message message;
//            MessageType messageType;
//            String messageData;
//            try {
//                while (true) {
//                    message = connection.receive();
//                    messageType = message.getType();
//                    messageData = message.getData();
//                    switch (messageType) {
//                        case NAME_REQUEST:
//                            throw new IOException("Unexpected MessageType");
//                        case USER_NAME:
//                            throw new IOException("Unexpected MessageType");
//                        case NAME_ACCEPTED:
//                            throw new IOException("Unexpected MessageType");
//                        case TEXT:
//                            processIncomingMessage(messageData);
//                            break;
//                        case USER_ADDED:
//                            informAboutAddingNewUser(messageData);
//                            break;
//                        case USER_REMOVED:
//                            informAboutDeletingNewUser(messageData);
//                            break;
//                        default:
//                            message = connection.receive();
//                    }
//
//                }
//            }catch (Exception e){throw new IOException("Unexpected MessageType");}
//        }

    }
}