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

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.onlab.osgi.ServiceDirectory;
import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiConnection;
import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.impl.UiWebSocket;
import org.onosproject.ui.model.topo.UiClusterMember;
import org.onosproject.ui.model.topo.UiDevice;
import org.onosproject.ui.model.topo.UiHost;
import org.onosproject.ui.model.topo.UiLink;
import org.onosproject.ui.model.topo.UiRegion;
import org.onosproject.ui.model.topo.UiTopoLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.List;
import java.util.Set;

import static org.onosproject.ui.model.topo.UiNode.LAYER_DEFAULT;

/*
 NOTES:

    The original topology view message handler was broken into two classes
    TopologyViewMessageHandler, and TopologyViewMessageHandlerBase.
    We do not need to follow that model necessarily. Starting with a
    single class, and breaking it apart later if necessary.

    Need to figure out the connection between this message handler and the
    new way of doing things with UiTopoSession...

 */

/**
 * Server-side component for interacting with the new "Region aware" topology
 * view in the Web UI.
 */
public class Topo2ViewMessageHandler extends UiMessageHandler {

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

    // === Inbound event identifiers
    private static final String TOPO2_START = "topo2Start";
    private static final String TOPO2_STOP = "topo2Stop";

    // === Outbound event identifiers
    private static final String ALL_INSTANCES = "topo2AllInstances";
    private static final String CURRENT_LAYOUT = "topo2CurrentLayout";
    private static final String CURRENT_REGION = "topo2CurrentRegion";
    private static final String PEER_REGIONS = "topo2PeerRegions";
    private static final String ORPHANS = "topo2Orphans";
    private static final String TOPO_START_DONE = "topo2StartDone";


    private UiTopoSession topoSession;
    private Topo2Jsonifier t2json;


    @Override
    public void init(UiConnection connection, ServiceDirectory directory) {
        super.init(connection, directory);

        // get the topo session from the UiWebSocket
        topoSession = ((UiWebSocket) connection).topoSession();
        t2json = new Topo2Jsonifier(directory);
    }

    @Override
    protected Collection<RequestHandler> createRequestHandlers() {
        return ImmutableSet.of(
                new Topo2Start(),
                new Topo2Stop()
        );
    }

    // ==================================================================


    private final class Topo2Start extends RequestHandler {
        private Topo2Start() {
            super(TOPO2_START);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            // client view is ready to receive data to display; so start up
            // server-side processing, and send over initial state

            log.debug("topo2Start: {}", payload);

            // this is the list of ONOS cluster members
            List<UiClusterMember> instances = topoSession.getAllInstances();
            sendMessage(ALL_INSTANCES, t2json.instances(instances));

            // this is the layout that the user has chosen to display
            UiTopoLayout currentLayout = topoSession.currentLayout();
            sendMessage(CURRENT_LAYOUT, t2json.layout(currentLayout));

            // this is the region that is associated with the current layout
            //   this message includes details of the sub-regions, devices,
            //   hosts, and links within the region
            //   (as well as layer-order hints)
            UiRegion region = topoSession.getRegion(currentLayout);
            Set<UiRegion> kids = topoSession.getSubRegions(currentLayout);
            sendMessage(CURRENT_REGION, t2json.region(region, kids));

            // these are the regions that are siblings to this one
            Set<UiRegion> peers = topoSession.getPeerRegions(currentLayout);
            ObjectNode peersPayload = objectNode();
            peersPayload.set("peers", t2json.closedRegions(peers));
            sendMessage(PEER_REGIONS, peersPayload);

            // return devices, hosts, links belonging to no region
            Set<UiDevice> oDevices = topoSession.getOrphanDevices();
            Set<UiHost> oHosts = topoSession.getOrphanHosts();
            Set<UiLink> oLinks = topoSession.getOrphanLinks();
            List<String> oLayers = getOrphanLayerOrder();
            sendMessage(ORPHANS, t2json.orphans(oDevices, oHosts, oLinks, oLayers));

            // finally, tell the UI that we are done
            sendMessage(TOPO_START_DONE, null);


            // OLD CODE DID THE FOLLOWING...
//            addListeners();
//            sendAllInstances(null);
//            sendAllDevices();
//            sendAllLinks();
//            sendAllHosts();
//            sendTopoStartDone();
        }


    }

    // TODO: we need to decide on how this should really get populated.
    // For example, to be "backward compatible", this should really be
    //  [ LAYER_OPTICAL, LAYER_PACKET, LAYER_DEFAULT ]
    private List<String> getOrphanLayerOrder() {
        // NOTE that LAYER_DEFAULT must always be last in the array
        return ImmutableList.of(LAYER_DEFAULT);
    }

    private final class Topo2Stop extends RequestHandler {
        private Topo2Stop() {
            super(TOPO2_STOP);
        }

        @Override
        public void process(long sid, ObjectNode payload) {
            // client view has gone away; so shut down server-side processing
            // TODO: implement...

            log.debug("topo2Stop: {}", payload);

            // OLD CODE DID THE FOLLOWING...
//            removeListeners();
//            stopSummaryMonitoring();
//            traffic.stopMonitoring();
        }
    }

}
