package org.onlab.onos.store.mastership.impl;

import java.util.Collections;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.cluster.RoleInfo;
import org.onlab.onos.net.MastershipRole;

import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;

/**
 * A structure that holds node mastership roles associated with a
 * {@link org.onlab.onos.net.DeviceId}. This structure needs to be locked through IMap.
 */
final class RoleValue {

    protected final Map<MastershipRole, List<NodeId>> value = new EnumMap<>(MastershipRole.class);

    public RoleValue() {
        value.put(MastershipRole.MASTER, new LinkedList<NodeId>());
        value.put(MastershipRole.STANDBY, new LinkedList<NodeId>());
        value.put(MastershipRole.NONE, new LinkedList<NodeId>());
    }

    // exposing internals for serialization purpose only
    Map<MastershipRole, List<NodeId>> value() {
        return Collections.unmodifiableMap(value);
    }

    public List<NodeId> nodesOfRole(MastershipRole type) {
        return value.get(type);
    }

    public NodeId get(MastershipRole type) {
        return value.get(type).isEmpty() ? null : value.get(type).get(0);
    }

    public boolean contains(MastershipRole type, NodeId nodeId) {
        return value.get(type).contains(nodeId);
    }

    /**
     * Associates a node to a certain role.
     *
     * @param type the role
     * @param nodeId the node ID of the node to associate
     */
    public void add(MastershipRole type, NodeId nodeId) {
        List<NodeId> nodes = value.get(type);

        if (!nodes.contains(nodeId)) {
            nodes.add(nodeId);
        }
    }

    /**
     * Removes a node from a certain role.
     *
     * @param type the role
     * @param nodeId the ID of the node to remove
     * @return
     */
    public boolean remove(MastershipRole type, NodeId nodeId) {
        List<NodeId> nodes = value.get(type);
        if (!nodes.isEmpty()) {
            return nodes.remove(nodeId);
        } else {
            return false;
        }
    }

    /**
     * Reassigns a node from one role to another. If the node was not of the
     * old role, it will still be assigned the new role.
     *
     * @param nodeId the Node ID of node changing roles
     * @param from the old role
     * @param to the new role
     */
    public void reassign(NodeId nodeId, MastershipRole from, MastershipRole to) {
        remove(from, nodeId);
        add(to, nodeId);
    }

    /**
     * Replaces a node in one role with another node. Even if there is no node to
     * replace, the new node is associated to the role.
     *
     * @param from the old NodeId to replace
     * @param to the new NodeId
     * @param type the role associated with the old NodeId
     */
    public void replace(NodeId from, NodeId to, MastershipRole type) {
        remove(type, from);
        add(type, to);
    }

    /**
     * Summarizes this RoleValue as a RoleInfo. Note that master and/or backups
     * may be empty, so the values should be checked for safety.
     *
     * @return the RoleInfo.
     */
    public RoleInfo roleInfo() {
        return new RoleInfo(
                get(MastershipRole.MASTER), nodesOfRole(MastershipRole.STANDBY));
    }

    @Override
    public String toString() {
        ToStringHelper helper = MoreObjects.toStringHelper(this.getClass());
        for (Map.Entry<MastershipRole, List<NodeId>> el : value.entrySet()) {
            helper.add(el.getKey().toString(), el.getValue());
        }
        return helper.toString();
    }
}
