package vut.msa.transport;

import org.apache.log4j.Logger;
import vut.msa.enums.Status;
import vut.msa.helpers.ClientHelper;
import vut.msa.pojos.Client;
import vut.msa.transport.exceptions.UnauthorizedException;
import vut.msa.utilities.StringUtilities;

public class CommunicationProtocol {

    private static final Logger log = Logger.getLogger(CommunicationProtocol.class);
    private static final int CLIENT_ID = 0;
    private static final int CLIENT_PSW = 1;

    private Status state = Status.WAITING;
    private Client commClient = null;

    public String processInput (String input) throws UnauthorizedException {

        String output = null;

        switch (state) {
            //Cakam na klienta, poziadam o identifikaciu
            case WAITING:
                output = "IDENTIFY";
                state = Status.SENTCREDENCIAL;
                break;
            //Overim uzivatela, ak OK pockam na akciu, ak nie zatvorim spojenie
            case SENTCREDENCIAL:
                //TODO: tu bude overovat uzivatela
                boolean authorized = false;

                String[] clientData = new StringUtilities().tokenizeString(input, "|");
                log.info("Authorizing user: "+ clientData[CLIENT_ID]);
                ClientHelper helper = new ClientHelper();
                commClient =
                        helper.authorizeClient(clientData[CLIENT_ID], clientData[CLIENT_PSW]);
                authorized = (commClient != null);

                if (authorized) {
                    state = Status.ACTION;
                    output = "TAKE_ACTION";
                } else {
                    //User is unauthorized
                    state = Status.WAITING;
                    output = "UNAUTHORIZED";
                    //throw new UnauthorizedException("Unauthorized:" + clientData[CLIENT_ID]);
                }
                break;

            case ACTION:
                log.info("Command received: " + input);
                if (input.equals("WRITE")) {
                    state = Status.READ;
                    output = "SEND_DATA";
                } else if (input.equals("READ")) {
                    state = Status.WRITE;
                    output = "READ_DATA";
                } else if (input.equals("INFO")) {
                    state = Status.INFO;
                    output = "SEND_INFO";
                } else {
                    state = Status.WAITING;
                    output = "ERR";
                }
                break;

            case READ:
                //Nacitaj data
                state = Status.ANOTHER;
                output = "READ_DATA";
                break;

            case WRITE:
                //Posli data
                state = Status.ANOTHER;
                output = "WRITE_DATA";
                break;

            case INFO:
                //Nacitaj info
                state = Status.ANOTHER;
                output = "READ_INFO";
                break;

            case ANOTHER:
                //Chce dalsiu akciu?
                if (input.equals("YES")) {
                    state = Status.ACTION;
                    output = "NEXT_ACTION";
                } else {
                    state = Status.WAITING;
                    output = "CLOSE";
                }
                break;
        }
        
        return output;
    }

    //PROPERTY: commClient
    public Client getCommClient() { return commClient; }

}
