/* 
 *  UserData.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.api.ContactCenterCodeI;
import com.avaya.ccs.api.MonitoredUserI;
import com.avaya.ccs.api.OffsiteStatusI;
import com.avaya.ccs.api.UserI;
import com.avaya.ccs.api.enums.UserSyncStatus;
import com.avaya.ccs.api.enums.ContactType;
import com.avaya.ccs.api.enums.Role;
import com.avaya.ccs.api.enums.UserState;
import com.avaya.ccs.api.exceptions.ObjectInvalidException;
import com.avaya.ccs.core.AgentSignature;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javafx.util.Pair;

public class UserData extends Data {

    // Properties
    private String id = "0";
    private List<ContactType> contactTypes = new ArrayList<>();
    private List<MonitoredUserI> monitoredUsers = new ArrayList<>();
    private ContactCenterCodeI code;
    private String firstName = "";
    private String lastName = "";
    private String fullName = "";
    private String loginId = "";
    private UserState state = UserState.Unknown;
    private String supervisorName = "";
    private boolean isMultimedia = false;
    private List<Role> role = new ArrayList<>();
    private String voiceResource = "";
    private OffsiteStatusI offSiteStatus;
    private UserSyncStatus userSyncStatus = UserSyncStatus.Unknown;
    private String userSyncMessage = "";

    // POM Properties
    private boolean pomNailedUp = false;
    private List<String> pomZones = new ArrayList<>();
    // Capabilities
    private boolean canAfterCallWork = false;
    private boolean canLogin = false;
    private boolean canLoginOffsite = false;
    private boolean canLogout = false;
    private boolean canMonitorUsers = false;
    private boolean canNotReady = false;
    private boolean canOriginateEmail = false;
    private boolean canReady = false;
    private boolean canRecoverOffsite = false;
    private boolean canUnmonitorUsers = false;
    
	private String agentSignature = null;

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

    public UserData(UserI user) {
        String methodName = "UserData() ";
        role.add(Role.Unknown);
        if (user != null) {
            try {
                // Properties
                this.id = user.getId();
                this.contactTypes = user.getContactTypes();
                this.monitoredUsers = user.getMonitoredUsers();
                this.code = user.getCode();
                this.firstName = user.getFirstName();
                this.lastName = user.getLastName();
                this.fullName = user.getFullName();
                this.loginId = user.getLoginId();
                this.state = user.getState();
                this.supervisorName = user.getSupervisorName();
                this.isMultimedia = user.isMultimedia();
                this.role = user.getRoles();
//                this.setAgentSignature(user.getAgentSignature()); //TODO add Agent Signature in a future release @conroy1
                this.voiceResource = user.getVoiceResource();
                this.offSiteStatus = user.getOffsiteStatus();
                this.userSyncStatus = user.getUserSyncStatus();

                if (this.userSyncStatus != UserSyncStatus.NotApplicable
                        && this.userSyncStatus != UserSyncStatus.Synchronised
                        && this.userSyncStatus != UserSyncStatus.Unknown) {
                    this.userSyncMessage = user.getUserSyncMessage();
                }
                // POM properties
                this.pomNailedUp = user.isPomNailedUp();
                this.pomZones = user.getPomZones();

                // Capabilities
                this.canAfterCallWork = user.canAfterCallWork();
                this.canLogin = user.canLogin();
                this.canLoginOffsite = user.canLoginOffsite();
                this.canLogout = user.canLogout();
                this.canMonitorUsers = user.canMonitorUsers();
                this.canNotReady = user.canNotReady();
                this.canOriginateEmail = user.canOriginateEmail();
                this.canReady = user.canReady();
                this.canRecoverOffsite = user.canRecoverOffsite();
                this.canUnmonitorUsers = user.canUnmonitorUsers();

            } catch (ObjectInvalidException ex) {
                LOG.error(methodName, "ObjectInvalidException while accessing user", ex);
                // Set all properties to default values
                this.id = "0";
                this.contactTypes = new ArrayList<>();
                this.monitoredUsers = new ArrayList<>();
                this.code = null;
                this.firstName = "";
                this.lastName = "";
                this.fullName = "";
                this.loginId = "";
                this.state = UserState.Unknown;
                this.supervisorName = "";
                this.isMultimedia = false;
                this.role = new ArrayList<>();
                this.role.add(Role.Unknown);
                this.voiceResource = "";
                this.pomNailedUp = false;
                this.pomZones = new ArrayList<>();
                this.userSyncStatus = UserSyncStatus.Unknown;
                this.userSyncMessage = "";
                // Set all capabilities to default values
                this.canAfterCallWork = false;
                this.canLogin = false;
                this.canLoginOffsite = false;
                this.canLogout = false;
                this.canMonitorUsers = false;
                this.canNotReady = false;
                this.canReady = false;
                this.canRecoverOffsite = false;
                this.canUnmonitorUsers = false;
            }
        }
    }

    public UserData(String id, boolean deleted) {
        this.id = id;
        this.setDeleted(deleted);
    }

    public String toString() {
        String str = "ID:" + id;
        // Properties
        str += " contactTypes:" + contactTypes + " monitoredUsers:" + monitoredUsers + " code:" + code + " firstName:"
                + firstName + " lastName:" + lastName + " fullName:" + fullName + " loginId:" + loginId + " state:"
                + state + " supervisorName:" + " isMultimedia:" + isMultimedia + " role:" + " voiceResource:"
                + voiceResource + " offSiteStatus:" + offSiteStatus + " userSyncStatus:" + userSyncStatus
                + " userSyncMessage:" + userSyncMessage;
        // POM Properties
        str += " pomNailedUp:" + pomNailedUp + " pomZones:";
        // Capabilities
        str += " canAfterCallWork:" + canAfterCallWork + " canLogin:" + canLogin + " canLoginOffsite:" + canLoginOffsite
                + " canLogout:" + canLogout + " canMonitorUsers:" + canMonitorUsers + " canNotReady:" + canNotReady
                + " canOriginateEmail: "+ canOriginateEmail + " canReady:" + canReady + " canRecoverOffsite:"
                + canRecoverOffsite + " canUnmonitorUsers:" + canUnmonitorUsers;
        return str;
    }

    @Override
    public List<Pair<String, String>> getProperties() {
        List<Pair<String, String>> properties = new LinkedList<>();
        properties.add(new Pair<String, String>("ID", this.getId()));
        properties.add(new Pair<String, String>("Contact Types", typesToString()));
        properties.add(new Pair<String, String>("Agents", agentsToString()));
        properties.add(new Pair<String, String>("Code", codeToString()));
        properties.add(new Pair<String, String>("First Name", this.getFirstName()));
        properties.add(new Pair<String, String>("Last Name", this.getLastName()));
        properties.add(new Pair<String, String>("Full Name", this.getFullName()));
        properties.add(new Pair<String, String>("Login ID", this.getLoginId()));
        properties.add(new Pair<String, String>("State", this.stateToString()));
        properties.add(new Pair<String, String>("Multimedia", Boolean.toString(this.isMultimedia())));
        properties.add(new Pair<String, String>("Roles ", this.rolesToString()));
        properties.add(new Pair<String, String>("Voice Resource ", this.getVoiceResource()));
        properties.add(new Pair<String, String>("POM NailedUp ", Boolean.toString(this.isPomNailedUp())));
        properties.add(new Pair<String, String>("POM Zones ", this.zonesToString()));
        properties.add(new Pair<String, String>("UserSyncStatus ", this.getUserSyncStatus().name()));
        properties.add(new Pair<String, String>("UserSyncMessage ", this.getUserSyncMessage()));
        return properties;
    }

    @Override
    public List<Pair<String, Boolean>> getCaps() {
        List<Pair<String, Boolean>> caps = new LinkedList<>();
        caps.add(new Pair<String, Boolean>("CanAfterCallWork", this.canAfterCallWork()));
        caps.add(new Pair<String, Boolean>("CanLogin", this.canLogin()));
        caps.add(new Pair<String, Boolean>("CanLoginOffsite", this.canLoginOffsite()));
        caps.add(new Pair<String, Boolean>("CanLogout", this.canLogout()));
        caps.add(new Pair<String, Boolean>("CanMonitorUsers", this.canMonitorUsers()));
        caps.add(new Pair<String, Boolean>("CanNotReady", this.canNotReady()));
        caps.add(new Pair<String, Boolean>("CanOriginateEmail", this.canOriginateEmail));
        caps.add(new Pair<String, Boolean>("CanReady", this.canReady()));
        caps.add(new Pair<String, Boolean>("CanRecoverOffsite", this.canRecoverOffsite()));
        caps.add(new Pair<String, Boolean>("CanUnmonitorUsers", this.canUnmonitorUsers()));
        return caps;
    }

    private String typesToString() {
        if (getContactTypes().isEmpty()) {
            return "NONE";
        }

        String types = "";
        for (ContactType type : getContactTypes()) {
            types += type.name() + " ";
        }
        return types;
    }

    private String agentsToString() {
        if (this.getMonitoredUsers().isEmpty()) {
            return "NONE";
        }

        String agentsAsString = "";
        for (MonitoredUserI agent : this.getMonitoredUsers()) {
            agentsAsString += agent.toString() + " ";
        }
        return agentsAsString;
    }

    private String codeToString() {
        if (this.getCode() == null) {
            return "<NULL>";
        } else {
            return getCode().getName() + " " + getCode().getNumber();
        }
    }

    private String stateToString() {
        if (this.state == null) {
            return "<NULL>";
        } else {
            return this.state.name();
        }
    }

    private String rolesToString() {
        String ret = "";
        for (Role r : this.role) {
            ret += r.name() + " ";
        }
        return ret;
    }

    private String zonesToString() {
        String ret = "";
        for (String zone : this.getPomZones()) {
            ret += zone;
        }
        return ret;
    }

    public UserState getState() {
        return this.state;
    }

    public OffsiteStatusI getOffSiteStatus() {
        return offSiteStatus;
    }

    @Override
    public String getId() {
        return id;
    }

    public List<ContactType> getContactTypes() {
        return contactTypes;
    }

    public List<MonitoredUserI> getMonitoredUsers() {
        return monitoredUsers;
    }

    public ContactCenterCodeI getCode() {
        return code;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getFullName() {
        return fullName;
    }

    public String getLoginId() {
        return loginId;
    }

    public String getSupervisorName() {
        return supervisorName;
    }

    public boolean isMultimedia() {
        return isMultimedia;
    }

    public boolean canAfterCallWork() {
        return canAfterCallWork;
    }

    public boolean canLogin() {
        return canLogin;
    }

    public boolean canLoginOffsite() {
        return canLoginOffsite;
    }

    public boolean canLogout() {
        return canLogout;
    }

    public boolean canMonitorUsers() {
        return canMonitorUsers;
    }

    public boolean canNotReady() {
        return canNotReady;
    }

    public boolean canOriginateEmail() {return canOriginateEmail; }

    public boolean canReady() {
        return canReady;
    }

    public boolean canRecoverOffsite() {
        return canRecoverOffsite;
    }

    public boolean canUnmonitorUsers() {
        return canUnmonitorUsers;
    }

    public boolean isPomNailedUp() {
        return pomNailedUp;
    }

    public List<String> getPomZones() {
        return pomZones;
    }

    public String getVoiceResource() {
        return voiceResource;
    }

    public UserSyncStatus getUserSyncStatus() {
        return userSyncStatus;
    }

    public String getUserSyncMessage() {
        return userSyncMessage;
    }

    @Override
    public void update(Data newData) {
        UserData newUserData = (UserData) newData;
        // Properties
        this.id = newUserData.getId();
        this.contactTypes = newUserData.getContactTypes();
        this.monitoredUsers = newUserData.getMonitoredUsers();
        this.code = newUserData.getCode();
        this.firstName = newUserData.getFirstName();
        this.lastName = newUserData.getLastName();
        this.fullName = newUserData.getFullName();
        this.loginId = newUserData.getLoginId();
        this.state = newUserData.getState();
        this.supervisorName = newUserData.getSupervisorName();
        this.isMultimedia = newUserData.isMultimedia();
        this.role = newUserData.role;
        this.voiceResource = newUserData.getVoiceResource();
        this.offSiteStatus = newUserData.getOffSiteStatus();
        this.userSyncStatus = newUserData.getUserSyncStatus();

        if (this.userSyncStatus != UserSyncStatus.NotApplicable && this.userSyncStatus != UserSyncStatus.Synchronised
                && this.userSyncStatus != UserSyncStatus.Unknown) {
            this.userSyncMessage = newUserData.getUserSyncMessage();
        }

        // POM Properties
        this.pomNailedUp = newUserData.isPomNailedUp();
        this.pomZones = newUserData.getPomZones();
        // Capabilities
        this.canAfterCallWork = newUserData.canAfterCallWork();
        this.canLogin = newUserData.canLogin();
        this.canLoginOffsite = newUserData.canLoginOffsite();
        this.canLogout = newUserData.canLogout();
        this.canMonitorUsers = newUserData.canMonitorUsers();
        this.canNotReady = newUserData.canNotReady();
        this.canOriginateEmail = newUserData.canOriginateEmail();
        this.canReady = newUserData.canReady();
        this.canRecoverOffsite = newUserData.canRecoverOffsite();
        this.canUnmonitorUsers = newUserData.canUnmonitorUsers();
    }

	public String getAgentSignature() {
		return agentSignature;
	}

	public void setAgentSignature(String agentSignature) {
		this.agentSignature = agentSignature;
	}
}
