/*
 *  Copyright 2016 Open Networking Laboratory
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.onosproject.ui.impl.topo.model;

import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.cluster.RoleInfo;
import org.onosproject.event.EventDispatcher;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.EdgeLink;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.Link;
import org.onosproject.net.region.Region;
import org.onosproject.net.region.RegionId;
import org.onosproject.ui.model.ServiceBundle;
import org.onosproject.ui.model.topo.UiClusterMember;
import org.onosproject.ui.model.topo.UiDevice;
import org.onosproject.ui.model.topo.UiElement;
import org.onosproject.ui.model.topo.UiHost;
import org.onosproject.ui.model.topo.UiLink;
import org.onosproject.ui.model.topo.UiLinkId;
import org.onosproject.ui.model.topo.UiRegion;
import org.onosproject.ui.model.topo.UiTopology;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.CLUSTER_MEMBER_ADDED_OR_UPDATED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.CLUSTER_MEMBER_REMOVED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_ADDED_OR_UPDATED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.DEVICE_REMOVED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_ADDED_OR_UPDATED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_MOVED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.HOST_REMOVED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.LINK_ADDED_OR_UPDATED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.LINK_REMOVED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.REGION_ADDED_OR_UPDATED;
import static org.onosproject.ui.impl.topo.model.UiModelEvent.Type.REGION_REMOVED;
import static org.onosproject.ui.model.topo.UiLinkId.uiLinkId;

/**
 * UI Topology Model cache.
 */
class ModelCache {

    private static final String E_NO_ELEMENT = "Tried to remove non-member {}: {}";

    private static final Logger log = LoggerFactory.getLogger(ModelCache.class);

    private final ServiceBundle services;
    private final EventDispatcher dispatcher;
    private final UiTopology uiTopology = new UiTopology();

    ModelCache(ServiceBundle services, EventDispatcher eventDispatcher) {
        this.services = services;
        this.dispatcher = eventDispatcher;
    }

    @Override
    public String toString() {
        return "ModelCache{" + uiTopology + "}";
    }

    private void postEvent(UiModelEvent.Type type, UiElement subject) {
        dispatcher.post(new UiModelEvent(type, subject));
    }

    void clear() {
        uiTopology.clear();
    }

    /**
     * Create our internal model of the global topology. An assumption we are
     * making is that the topology is empty to start.
     */
    void load() {
        loadClusterMembers();
        loadRegions();
        loadDevices();
        loadLinks();
        loadHosts();
    }


    // === CLUSTER MEMBERS

    private UiClusterMember addNewClusterMember(ControllerNode n) {
        UiClusterMember member = new UiClusterMember(uiTopology, n);
        uiTopology.add(member);
        return member;
    }

    private void updateClusterMember(UiClusterMember member) {
        ControllerNode.State state = services.cluster().getState(member.id());
        member.setState(state);
        member.setMastership(services.mastership().getDevicesOf(member.id()));
        // NOTE: 'UI-attached' is session-based data, not global, so will
        //       be set elsewhere
    }

    private void loadClusterMembers() {
        for (ControllerNode n : services.cluster().getNodes()) {
            UiClusterMember member = addNewClusterMember(n);
            updateClusterMember(member);
        }
    }

    // invoked from UiSharedTopologyModel cluster event listener
    void addOrUpdateClusterMember(ControllerNode cnode) {
        NodeId id = cnode.id();
        UiClusterMember member = uiTopology.findClusterMember(id);
        if (member == null) {
            member = addNewClusterMember(cnode);
        }
        updateClusterMember(member);

        postEvent(CLUSTER_MEMBER_ADDED_OR_UPDATED, member);
    }

    // package private for unit test access
    UiClusterMember accessClusterMember(NodeId id) {
        return uiTopology.findClusterMember(id);
    }

    // invoked from UiSharedTopologyModel cluster event listener
    void removeClusterMember(ControllerNode cnode) {
        NodeId id = cnode.id();
        UiClusterMember member = uiTopology.findClusterMember(id);
        if (member != null) {
            uiTopology.remove(member);
            postEvent(CLUSTER_MEMBER_REMOVED, member);
        } else {
            log.warn(E_NO_ELEMENT, "cluster node", id);
        }
    }

    List<UiClusterMember> getAllClusterMembers() {
        return uiTopology.allClusterMembers();
    }


    // === MASTERSHIP CHANGES

    // invoked from UiSharedTopologyModel mastership listener
    void updateMasterships(DeviceId deviceId, RoleInfo roleInfo) {
        // To think about:: do we need to store mastership info?
        //  or can we rely on looking it up live?
        // TODO: store the updated mastership information
        // TODO: post event
    }

    // === THE NULL REGION

    UiRegion nullRegion() {
        return uiTopology.nullRegion();
    }

    // === REGIONS

    private UiRegion addNewRegion(Region r) {
        UiRegion region = new UiRegion(uiTopology, r);
        uiTopology.add(region);
        log.debug("Region {} added to topology", region);
        return region;
    }

    private void updateRegion(UiRegion region) {
        RegionId rid = region.id();
        Set<DeviceId> deviceIds = services.region().getRegionDevices(rid);

        // Make sure device objects refer to their region
        deviceIds.forEach(d -> {
            UiDevice dev = uiTopology.findDevice(d);
            if (dev != null) {
                dev.setRegionId(rid);
            } else {
                // if we don't have the UiDevice in the topology, what can we do?
                log.warn("Region device {}, but we don't have UiDevice in topology", d);
            }
        });

        // Make sure the region object refers to the devices
        region.reconcileDevices(deviceIds);
    }

    private void loadRegions() {
        for (Region r : services.region().getRegions()) {
            UiRegion region = addNewRegion(r);
            updateRegion(region);
        }
    }

    // invoked from UiSharedTopologyModel region listener
    void addOrUpdateRegion(Region region) {
        RegionId id = region.id();
        UiRegion uiRegion = uiTopology.findRegion(id);
        if (uiRegion == null) {
            uiRegion = addNewRegion(region);
        }
        updateRegion(uiRegion);

        postEvent(REGION_ADDED_OR_UPDATED, uiRegion);
    }

    // package private for unit test access
    UiRegion accessRegion(RegionId id) {
        return id == null ? null : uiTopology.findRegion(id);
    }

    // invoked from UiSharedTopologyModel region listener
    void removeRegion(Region region) {
        RegionId id = region.id();
        UiRegion uiRegion = uiTopology.findRegion(id);
        if (uiRegion != null) {
            uiTopology.remove(uiRegion);
            postEvent(REGION_REMOVED, uiRegion);
        } else {
            log.warn(E_NO_ELEMENT, "region", id);
        }
    }


    // === DEVICES

    private UiDevice addNewDevice(Device d) {
        UiDevice device = new UiDevice(uiTopology, d);
        updateDevice(device);
        uiTopology.add(device);
        log.debug("Device {} added to topology", device);
        return device;
    }

    // make sure the UiDevice is tagged with the region it belongs to
    private void updateDevice(UiDevice device) {
        Region r = services.region().getRegionForDevice(device.id());
        RegionId rid = r == null ? UiRegion.NULL_ID : r.id();
        device.setRegionId(rid);
    }

    private void loadDevices() {
        for (Device d : services.device().getDevices()) {
            addNewDevice(d);
        }
    }

    // invoked from UiSharedTopologyModel device listener
    void addOrUpdateDevice(Device device) {
        DeviceId id = device.id();
        UiDevice uiDevice = uiTopology.findDevice(id);
        if (uiDevice == null) {
            uiDevice = addNewDevice(device);
        } else {
            updateDevice(uiDevice);
        }

        postEvent(DEVICE_ADDED_OR_UPDATED, uiDevice);
    }

    // package private for unit test access
    UiDevice accessDevice(DeviceId id) {
        return uiTopology.findDevice(id);
    }

    // invoked from UiSharedTopologyModel device listener
    void removeDevice(Device device) {
        DeviceId id = device.id();
        UiDevice uiDevice = uiTopology.findDevice(id);
        if (uiDevice != null) {
            uiTopology.remove(uiDevice);
            postEvent(DEVICE_REMOVED, uiDevice);
        } else {
            log.warn(E_NO_ELEMENT, "device", id);
        }
    }


    // === LINKS

    private UiLink addNewLink(UiLinkId id) {
        UiLink uiLink = new UiLink(uiTopology, id);
        uiTopology.add(uiLink);
        return uiLink;
    }

    private void updateLink(UiLink uiLink, Link link) {
        uiLink.attachBackingLink(link);
    }

    private void loadLinks() {
        for (Link link : services.link().getLinks()) {
            UiLinkId id = uiLinkId(link);

            UiLink uiLink = uiTopology.findLink(id);
            if (uiLink == null) {
                uiLink = addNewLink(id);
            }
            updateLink(uiLink, link);
        }
    }

    // invoked from UiSharedTopologyModel link listener
    void addOrUpdateLink(Link link) {
        UiLinkId id = uiLinkId(link);
        UiLink uiLink = uiTopology.findLink(id);
        if (uiLink == null) {
            uiLink = addNewLink(id);
        }
        updateLink(uiLink, link);

        postEvent(LINK_ADDED_OR_UPDATED, uiLink);
    }

    // package private for unit test access
    UiLink accessLink(UiLinkId id) {
        return uiTopology.findLink(id);
    }

    // invoked from UiSharedTopologyModel link listener
    void removeLink(Link link) {
        UiLinkId id = uiLinkId(link);
        UiLink uiLink = uiTopology.findLink(id);
        if (uiLink != null) {
            boolean remaining = uiLink.detachBackingLink(link);
            if (remaining) {
                postEvent(LINK_ADDED_OR_UPDATED, uiLink);
            } else {
                uiTopology.remove(uiLink);
                postEvent(LINK_REMOVED, uiLink);
            }
        } else {
            log.warn(E_NO_ELEMENT, "link", id);
        }
    }


    // === HOSTS

    private EdgeLink synthesizeLink(Host h) {
        return createEdgeLink(h, true);
    }

    private UiHost addNewHost(Host h) {
        UiHost host = new UiHost(uiTopology, h);
        uiTopology.add(host);

        EdgeLink elink = synthesizeLink(h);
        UiLinkId elinkId = uiLinkId(elink);
        host.setEdgeLinkId(elinkId);

        // add synthesized edge link to the topology
        UiLink edgeLink = addNewLink(elinkId);
        edgeLink.attachEdgeLink(elink);

        return host;
    }

    private void insertNewUiLink(UiLinkId id, EdgeLink e) {
        UiLink newEdgeLink = addNewLink(id);
        newEdgeLink.attachEdgeLink(e);

    }

    private void updateHost(UiHost uiHost, Host h) {
        UiLink existing = uiTopology.findLink(uiHost.edgeLinkId());

        EdgeLink currentElink = synthesizeLink(h);
        UiLinkId currentElinkId = uiLinkId(currentElink);

        if (existing != null) {
            if (!currentElinkId.equals(existing.id())) {
                // edge link has changed
                insertNewUiLink(currentElinkId, currentElink);
                uiHost.setEdgeLinkId(currentElinkId);

                uiTopology.remove(existing);
            }

        } else {
            // no previously existing edge link
            insertNewUiLink(currentElinkId, currentElink);
            uiHost.setEdgeLinkId(currentElinkId);

        }

        HostLocation hloc = h.location();
        uiHost.setLocation(hloc.deviceId(), hloc.port());
    }

    private void loadHosts() {
        for (Host h : services.host().getHosts()) {
            UiHost host = addNewHost(h);
            updateHost(host, h);
        }
    }

    // invoked from UiSharedTopologyModel host listener
    void addOrUpdateHost(Host host) {
        HostId id = host.id();
        UiHost uiHost = uiTopology.findHost(id);
        if (uiHost == null) {
            uiHost = addNewHost(host);
        }
        updateHost(uiHost, host);

        postEvent(HOST_ADDED_OR_UPDATED, uiHost);
    }

    // invoked from UiSharedTopologyModel host listener
    void moveHost(Host host, Host prevHost) {
        UiHost uiHost = uiTopology.findHost(prevHost.id());
        if (uiHost != null) {
            updateHost(uiHost, host);
            postEvent(HOST_MOVED, uiHost);
        } else {
            log.warn(E_NO_ELEMENT, "host", prevHost.id());
        }
    }

    // package private for unit test access
    UiHost accessHost(HostId id) {
        return uiTopology.findHost(id);
    }

    // invoked from UiSharedTopologyModel host listener
    void removeHost(Host host) {
        HostId id = host.id();
        UiHost uiHost = uiTopology.findHost(id);
        if (uiHost != null) {
            UiLink edgeLink = uiTopology.findLink(uiHost.edgeLinkId());
            uiTopology.remove(edgeLink);
            uiTopology.remove(uiHost);
            postEvent(HOST_REMOVED, uiHost);
        } else {
            log.warn(E_NO_ELEMENT, "host", id);
        }
    }


    /**
     * Refreshes the internal state.
     */
    public void refresh() {
        // fix up internal linkages if they aren't correct

        // at the moment, this is making sure devices are in the correct region
        Set<UiDevice> allDevices = uiTopology.allDevices();

        services.region().getRegions().forEach(r -> {
            RegionId rid = r.id();
            UiRegion region = uiTopology.findRegion(rid);
            if (region != null) {
                Set<DeviceId> deviceIds = services.region().getRegionDevices(rid);
                region.reconcileDevices(deviceIds);

                deviceIds.forEach(devId -> {
                    UiDevice dev = uiTopology.findDevice(devId);
                    if (dev != null) {
                        dev.setRegionId(r.id());
                        allDevices.remove(dev);
                    } else {
                        log.warn("Region device ID {} but no UiDevice in topology",
                                devId);
                    }
                });
            } else {
                log.warn("No UiRegion in topology for ID {}", rid);
            }
        });

        // what is left over, must belong to the null-region
        Set<DeviceId> leftOver = new HashSet<>(allDevices.size());
        allDevices.forEach(d -> leftOver.add(d.id()));
        uiTopology.nullRegion().reconcileDevices(leftOver);
    }

    // === CACHE STATISTICS

    /**
     * Returns a detailed (multi-line) string showing the contents of the cache.
     *
     * @return detailed string
     */
    public String dumpString() {
        return uiTopology.dumpString();
    }

    /**
     * Returns the number of members in the cluster.
     *
     * @return number of cluster members
     */
    public int clusterMemberCount() {
        return uiTopology.clusterMemberCount();
    }

    /**
     * Returns the number of regions in the topology.
     *
     * @return number of regions
     */
    public int regionCount() {
        return uiTopology.regionCount();
    }

    /**
     * Returns the number of devices in the topology.
     *
     * @return number of devices
     */
    public int deviceCount() {
        return uiTopology.deviceCount();
    }

    /**
     * Returns the number of links in the topology.
     *
     * @return number of links
     */
    public int linkCount() {
        return uiTopology.linkCount();
    }

    /**
     * Returns the number of hosts in the topology.
     *
     * @return number of hosts
     */
    public int hostCount() {
        return uiTopology.hostCount();
    }

}
