/* 
 *  ResourceData.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.ResourceI;
import com.avaya.ccs.api.enums.ContactType;
import com.avaya.ccs.api.enums.ResourceState;
import com.avaya.ccs.api.enums.StateReason;
import com.avaya.ccs.api.exceptions.ObjectInvalidException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javafx.util.Pair;

/**
 * This class is a holder for resource related data. The reason for this holder
 * class is so that GUI components can access the data without having to dip
 * back into the SDK.
 */
public class ResourceData extends Data {

    // Capabilities
    private boolean canCallSupervisor = false;
    private boolean canOriginate = false;
    // Properties
    private String address = "";
    private String addressName = "";
    private List<ContactType> contactTypes = new ArrayList<>();
    private ContactType defaultContactType = ContactType.Unknown;
    private String id = "0";
    private ResourceState state = ResourceState.Unknown;
    private StateReason stateReason = StateReason.Unknown;
    private String stateReasonMessage = "";

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

    public ResourceData(ResourceI resource) {
        String methodName = "ResourceData() ";
        if (resource != null) {

            try {
                // Capabilities
                canCallSupervisor = resource.canCallSupervisor();
                canOriginate = resource.canOriginate();

                // Properties
                address = resource.getAddress();
                addressName = resource.getAddressName();
                contactTypes = resource.getContactTypes();
                defaultContactType = resource.getDefaultContactType();
                id = resource.getId();
                state = resource.getState();
                stateReason = resource.getStateReason();
                stateReasonMessage = resource.getStateReasonMessage();
            } catch (ObjectInvalidException ex) {
                LOG.error(methodName, "ObjectInvalidException while accessing resource", ex);
                // Assume the whole object is invalid
                canCallSupervisor = false;
                canOriginate = false;
                address = "";
                addressName = "";
                contactTypes = new ArrayList<>();
                defaultContactType = ContactType.Unknown;
                id = "0";
                state = ResourceState.Unknown;
                stateReason = StateReason.Unknown;
                stateReasonMessage = "";
            }
        }

    }

    public String toString() {
        String str = "ID:" + id;
        // Properties
        str += " address:" + address + " addressName:" + addressName + " contactTypes:" + contactTypes
                + " defaultContactType:" + defaultContactType + " state:" + state.name() + " stateReason:" + stateReason
                + " stateReasonMessage:" + stateReasonMessage;
        // Capabilities
        str += " canCallSupervisor:" + canCallSupervisor + " canOriginate:" + canOriginate;
        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>("Default Contact Type", this.getDefaultContactType().name()));
        properties.add(new Pair<String, String>("Address", this.getAddress()));
        properties.add(new Pair<String, String>("AddressName", this.getAddressName()));
        properties.add(new Pair<String, String>("State", stateToString()));
        properties.add(new Pair<String, String>("StateReason", this.getStateReason().name()));
        properties.add(new Pair<String, String>("StateReasonMessage", this.getStateReasonMessage()));
        return properties;
    }

    @Override
    public List<Pair<String, Boolean>> getCaps() {
        List<Pair<String, Boolean>> caps = new LinkedList<>();
        caps.add(new Pair<String, Boolean>("CanCallSupervisor", this.canCallSupervisor()));
        caps.add(new Pair<String, Boolean>("CanOriginate", this.canOriginate()));
        return caps;
    }

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

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

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

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

    public boolean canCallSupervisor() {
        return canCallSupervisor;
    }

    public boolean canOriginate() {
        return canOriginate;
    }

    public String getAddress() {
        return address;
    }

    public String getAddressName() {
        return addressName;
    }

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

    public ContactType getDefaultContactType() {
        return defaultContactType;
    }

    public ResourceState getState() {
        return state;
    }

    public StateReason getStateReason() {
        return stateReason;
    }

    public String getStateReasonMessage() {
        return stateReasonMessage;
    }

    @Override
    public void update(Data newData) {
        ResourceData newResourceData = (ResourceData) newData;
        // Capabilities
        this.canCallSupervisor = newResourceData.canCallSupervisor();
        this.canOriginate = newResourceData.canOriginate();
        // Properties
        this.address = newResourceData.getAddress();
        this.addressName = newResourceData.getAddressName();
        this.contactTypes = newResourceData.getContactTypes();
        this.defaultContactType = newResourceData.getDefaultContactType();
        this.id = newResourceData.getId();
        this.state = newResourceData.getState();
        this.stateReason = newResourceData.getStateReason();
        this.stateReasonMessage = newResourceData.getStateReasonMessage();
    }
}
