/* 
 *  ClientSessionExecutor.java
 * 
 *  Copyright 2016 Avaya Inc. All Rights Reserved.
 * 
 *  Usage of this source is bound to the terms described
 *  in AvayaLicenseSDK.rtf.
 * 
 *  Avaya - Confidential & Proprietary. Use pursuant to your signed agreement
 *  or Avaya Policy
 * 
 */
package com.avaya.ccs.javafxrefclient;

import com.avaya.ccs.javafxrefclient.request.GetSessionDataRequest;
import com.avaya.ccs.javafxrefclient.request.DisconnectRequest;
import com.avaya.ccs.javafxrefclient.request.GetClientDataRequest;
import com.avaya.ccs.javafxrefclient.request.GetSessionCodesRequest;
import com.avaya.ccs.javafxrefclient.request.SignInRequest;
import com.avaya.ccs.api.enums.Command;
import com.avaya.ccs.api.*;
import com.avaya.ccs.api.enums.CodeType;
import com.avaya.ccs.api.enums.NotificationType;
import com.avaya.ccs.api.exceptions.InvalidArgumentException;
import com.avaya.ccs.api.exceptions.ObjectInvalidException;
import javafx.concurrent.Task;

public class ClientSessionExecutor extends Executor implements ClientListenerI, SessionListenerI {

    private static final Logger LOG = Logger.getLogger(ClientSessionExecutor.class);

    private ClientI client;
    private final JavaFXRefClient gui;

    public ClientSessionExecutor(JavaFXRefClient gui) {
        this.gui = gui;
    }

    public ClientI getClient() {
        return this.client;
    }

    public void setClient(ClientI client) {
        this.client = client;
    }

    public void disconnect() {
        String methodName = "disconnect() ";
        LOG.trace(methodName + "+");
        executeOutgoingRequest(new DisconnectRequest());
        LOG.trace(methodName + "-");
    }

    /**
     * Register listeners in response to new session
     */
    public void processNewSession() {
        String methodName = "processNewSession() ";
        try {
            SessionI session = client.getSession();
            int numberOfUsers = session.getNumUsers();
            if (numberOfUsers > 0) {
                LOG.debug(methodName + "NumUsers:" + numberOfUsers);
            } else {
                LOG.error(methodName + "No users in session.");
            }
            LOG.trace(methodName + "Registering User listener");
            session.openUsers(getUser());

            LOG.trace(methodName + "Registering Resource listener");
            session.openResources(getResource());

            LOG.trace(methodName + "Registering Interaction listener");
            session.openInteractions(getInteractionExe());
            
//            LOG.trace(methodName + "Registering Customer listener");
//            session.openCustomer(getCustomerExe());
            
        } catch (ObjectInvalidException | InvalidArgumentException e) {
            LOG.error(methodName + "error received " + e);
        }
    }

    public void signinClient(ConnectionDetails connectionDetails) {
        String methodName = "signinClient() ";
        LOG.debug(methodName + "+");
        executeOutgoingRequest(new SignInRequest(this, connectionDetails));
        LOG.trace(methodName + "-");
    }

    public void getClientData() {
        String methodName = "getClientData() ";
        LOG.debug(methodName + "+");
        executeOutgoingRequest(new GetClientDataRequest(gui));
        LOG.trace(methodName + "-");
    }

    public void getSessionData() {
        String methodName = "getSessionData() ";
        LOG.debug(methodName + "+");
        executeOutgoingRequest(new GetSessionDataRequest(gui));
        LOG.trace(methodName + "-");
    }

    public void getSessionCodes(CodeType type) {
        String methodName = "getSessionCodes";
        LOG.debug(methodName + "+ CodeType:" + type);
        executeOutgoingRequest(new GetSessionCodesRequest(gui.getUserGUI(), type));
        LOG.trace(methodName + "-");
    }

    @Override
    public void onClientEvent(NotificationEventI<ClientI> client) {
        String methodName = "onClientEvent() ";
        LOG.info(methodName + "Type:" + client.getNotificationType());
        if (client.getNotificationType() == NotificationType.ERROR) {
            ErrorI error = client.getError();
            Command command = error.getCommand();
            LOG.error(methodName + "error = " + error + " command=" + command);
        }

        Task<ClientData> t = new ClientEventTask(client.getNotificationType(), client.getNotificationObject(), gui);
        executeIncomingEvent(t);
    }

    @Override
    public void onSessionEvent(NotificationEventI<SessionI> session) {
        String methodName = "onSessionEvent() ";
        /*
         * Note the SessionI object can be null if there is a signin authentication error 
         */
        LOG.info(methodName + "Type:" + session.getNotificationType() + " SessionI-ID:"
                + (session.getNotificationObject() != null ? session.getNotificationObject().getId() : "null"));
        Task<SessionData> t = new SessionEventTask(session, this, gui);
        executeIncomingEvent(t);
    }
}
