/*
 *  Copyright 2016-present Open Networking Foundation
 *
 *  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;

import org.onosproject.net.region.RegionId;
import org.onosproject.ui.UiTopoLayoutService;
import org.onosproject.ui.impl.UiWebSocket;
import org.onosproject.ui.model.topo.UiLinkId;
import org.onosproject.ui.model.topo.UiModelEvent;
import org.onosproject.ui.impl.topo.model.UiModelListener;
import org.onosproject.ui.impl.topo.model.UiSharedTopologyModel;
import org.onosproject.ui.model.topo.UiClusterMember;
import org.onosproject.ui.model.topo.UiNode;
import org.onosproject.ui.model.topo.UiRegion;
import org.onosproject.ui.model.topo.UiSynthLink;
import org.onosproject.ui.model.topo.UiTopoLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * Coordinates with the {@link UiTopoLayoutService} to access
 * {@link UiTopoLayout}s, and with the {@link UiSharedTopologyModel} which
 * maintains a local model of the network entities, tailored specifically
 * for displaying on the UI.
 * <p>
 * Note that an instance of this class will be created for each
 * {@link UiWebSocket} connection, and will contain
 * the state of how the topology is laid out for the logged-in user.
 * <p>
 * The expected pattern is for the {@link Topo2ViewMessageHandler} to obtain
 * a reference to the session instance (via the {@link UiWebSocket}), and
 * interact with it when topo-related events come in from the client.
 */
public class UiTopoSession implements UiModelListener {

    private static final String TOPO2_UI_MODEL_EVENT = "topo2UiModelEvent";

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final UiWebSocket webSocket;
    private final String username;
    private final Topo2Jsonifier t2json;

    final UiSharedTopologyModel sharedModel;

    private boolean registered = false;

    private UiTopoLayoutService layoutService;
    private UiTopoLayout currentLayout;
    private boolean messagesEnabled = true;

    /**
     * Creates a new topology session for the specified web socket connection,
     * and references to JSONifier, shared model, and layout service.
     *
     * @param webSocket     web socket
     * @param jsonifier     JSONifier instance
     * @param model         share topology model
     * @param layoutService topology layout service
     */
    public UiTopoSession(UiWebSocket webSocket,
                         Topo2Jsonifier jsonifier,
                         UiSharedTopologyModel model,
                         UiTopoLayoutService layoutService) {
        this.webSocket = webSocket;
        this.username = webSocket.userName();
        this.t2json = jsonifier;
        this.sharedModel = model;
        this.layoutService = layoutService;
    }

    // constructs a neutered instance, for unit testing
    UiTopoSession() {
        webSocket = null;
        username = null;
        t2json = null;
        sharedModel = null;
    }

    /**
     * Initializes the session; registering with the shared model.
     */
    public void init() {
        if (!registered) {
            log.debug("{} : Registering with shared model", this);
            sharedModel.register(this);
            currentLayout = layoutService.getRootLayout();
            registered = true;
        } else {
            log.warn("already registered");
        }
    }

    /**
     * Destroys the session; unregistering from the shared model.
     */
    public void destroy() {
        if (registered) {
            log.debug("{} : Unregistering from shared model", this);
            sharedModel.unregister(this);
            registered = false;
        } else {
            log.warn("already unregistered");
        }
    }

    @Override
    public String toString() {
        return String.format("{UiTopoSession for user <%s>}", username);
    }

    @Override
    public boolean isRelevant(UiModelEvent event) {
        if (!messagesEnabled) {
            return false;
        }
        UiRegion uiRegion = sharedModel.getRegion(currentLayout.regionId());
        return uiRegion.isRelevant(event);
    }

    @Override
    public void event(UiModelEvent event) {
        webSocket.sendMessage(TOPO2_UI_MODEL_EVENT, t2json.jsonEvent(event));
    }

    /**
     * Returns the current layout context.
     *
     * @return current topology layout
     */
    public UiTopoLayout currentLayout() {
        return currentLayout;
    }

    /**
     * Returns the breadcrumb trail from current layout to root. That is,
     * element 0 of the list will be the current layout; the last element
     * of the list will be the root layout. This list is guaranteed to have
     * size of at least 1.
     *
     * @return breadcrumb trail
     */
    public List<UiTopoLayout> breadCrumbs() {
        UiTopoLayout current = currentLayout;
        List<UiTopoLayout> crumbs = new ArrayList<>();
        crumbs.add(current);
        while (!current.isRoot()) {
            current = layoutService.getLayout(current.parent());
            crumbs.add(current);
        }
        return crumbs;
    }

    /**
     * Changes the current layout context to the specified layout.
     *
     * @param topoLayout new topology layout context
     */
    public void setCurrentLayout(UiTopoLayout topoLayout) {
        currentLayout = topoLayout;
    }

    /**
     * Enables or disables the transmission of topology event update messages.
     *
     * @param enabled true if messages should be sent
     */
    public void enableEvent(boolean enabled) {
        messagesEnabled = enabled;
    }

    /**
     * Returns the list of ONOS instances (cluster members).
     *
     * @return the list of ONOS instances
     */
    public List<UiClusterMember> getAllInstances() {
        return sharedModel.getClusterMembers();
    }

    /**
     * Returns the region for the specified layout.
     *
     * @param layout layout filter
     * @return region that the layout is based upon
     */
    public UiRegion getRegion(UiTopoLayout layout) {
        RegionId rid = layout.regionId();
        return rid == null ? sharedModel.getNullRegion() : sharedModel.getRegion(rid);
    }

    /**
     * Returns the regions/devices that are "peers" to this region. That is,
     * based on the layout the user is viewing, all the regions/devices that
     * are associated with layouts that share the same parent layout as this
     * layout, AND that are linked to an element within this region.
     *
     * @param layout the layout being viewed
     * @return all regions/devices that are "siblings" to this layout's region
     */
    public Set<UiNode> getPeerNodes(UiTopoLayout layout) {
        Set<UiNode> peers = new HashSet<>();

        // first, get the peer regions
        Set<UiTopoLayout> peerLayouts = layoutService.getPeerLayouts(layout.id());
        peerLayouts.forEach(l -> {
            RegionId peerRegion = l.regionId();
            peers.add(sharedModel.getRegion(peerRegion));
        });

        // now add the devices that reside in the parent region
        if (!layout.isRoot()) {
            UiTopoLayout parentLayout = layoutService.getLayout(layout.parent());
            peers.addAll(getRegion(parentLayout).devices());
        }

        // TODO: Finally, filter out regions / devices that are not connected
        //       directly to this region by an implicit link
        return peers;
    }

    /**
     * Returns the subregions of the region in the specified layout.
     *
     * @param layout the layout being viewed
     * @return all regions that are "contained within" this layout's region
     */
    public Set<UiRegion> getSubRegions(UiTopoLayout layout) {
        Set<UiTopoLayout> kidLayouts = layoutService.getChildren(layout.id());
        Set<UiRegion> kids = new HashSet<>();
        kidLayouts.forEach(l -> kids.add(sharedModel.getRegion(l.regionId())));
        return kids;
    }

    /**
     * Returns the (synthetic) links of the region in the specified layout.
     *
     * @param layout the layout being viewed
     * @return all links that are contained by this layout's region
     */
    public List<UiSynthLink> getLinks(UiTopoLayout layout) {
        return sharedModel.getSynthLinks(layout.regionId());
    }

    /**
     * Refreshes the model's internal state.
     */
    public void refreshModel() {
        sharedModel.refresh();
    }

    /**
     * Navigates to the specified region by setting the associated layout as
     * current.
     *
     * @param regionId region identifier
     */
    public void navToRegion(String regionId) {
        // 1. find the layout corresponding to the region ID
        // 2. set this layout to be "current"
        RegionId r = RegionId.regionId(regionId);
        UiTopoLayout layout = layoutService.getLayout(r);
        setCurrentLayout(layout);
    }

    /**
     * Returns synthetic links that are in the current region, mapped by
     * original link ID.
     *
     * @return map of synth links
     */
    public Map<UiLinkId, UiSynthLink> relevantSynthLinks() {
        return sharedModel.relevantSynthLinks(currentLayout.regionId());
    }
}
