/*
 * 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.incubator.net.virtual.impl;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.incubator.net.virtual.DefaultVirtualLink;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.VirtualNetworkProvider;
import org.onosproject.incubator.net.virtual.VirtualNetworkProviderRegistry;
import org.onosproject.incubator.net.virtual.VirtualNetworkProviderService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyCluster;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyService;
import org.slf4j.Logger;

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

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Virtual network topology provider.
 */
@Component(immediate = true)
@Service
public class VirtualNetworkTopologyProvider extends AbstractProvider implements VirtualNetworkProvider {

    private final Logger log = getLogger(VirtualNetworkTopologyProvider.class);

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected VirtualNetworkProviderRegistry providerRegistry;

    private VirtualNetworkProviderService providerService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TopologyService topologyService;

    protected TopologyListener topologyListener = new InternalTopologyListener();

    /**
     * Default constructor.
     */
    public VirtualNetworkTopologyProvider() {
        super(DefaultVirtualLink.PID);
    }

    @Activate
    public void activate() {
        providerService = providerRegistry.register(this);
        topologyService.addListener(topologyListener);

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        topologyService.removeListener(topologyListener);
        providerRegistry.unregister(this);
        providerService = null;
        log.info("Stopped");
    }

    @Override
    public boolean isTraversable(ConnectPoint src, ConnectPoint dst) {
        final boolean[] foundSrc = new boolean[1];
        final boolean[] foundDst = new boolean[1];
        Topology topology = topologyService.currentTopology();
        Set<Path> paths = topologyService.getPaths(topology, src.deviceId(), dst.deviceId());
        paths.forEach(path -> {
            foundDst[0] = false;
            foundSrc[0] = false;
            // Traverse the links in each path to determine if both the src and dst connection
            // point are in the path, if so then this src/dst pair are traversable.
            path.links().forEach(link -> {
                if (link.src().equals(src)) {
                    foundSrc[0] = true;
                }
                if (link.dst().equals(dst)) {
                    foundDst[0] = true;
                }
            });
            if (foundSrc[0] && foundDst[0]) {
                return;
            }
        });
        return foundSrc[0] && foundDst[0];
    }

    @Override
    public TunnelId createTunnel(NetworkId networkId, ConnectPoint src, ConnectPoint dst) {
        return null;
    }

    @Override
    public void destroyTunnel(NetworkId networkId, TunnelId tunnelId) {

    }

    /**
     * Returns a set of set of interconnected connect points in the default topology.
     * The inner set represents the interconnected connect points, and the outerset
     * represents separate clusters.
     *
     * @param topology the default topology
     * @return set of set of interconnected connect points.
     */
    protected Set<Set<ConnectPoint>> getConnectPoints(Topology topology) {
        Set<Set<ConnectPoint>> clusters = new HashSet<>();
        Set<TopologyCluster> topologyClusters = topologyService.getClusters(topology);
        topologyClusters.forEach(topologyCluster -> {
            Set<ConnectPoint> connectPointSet = new HashSet<>();
            Set<Link> clusterLinks = topologyService.getClusterLinks(topology, topologyCluster);
            clusterLinks.forEach(link -> {
                connectPointSet.add(link.src());
                connectPointSet.add(link.dst());
            });
            if (!connectPointSet.isEmpty()) {
                clusters.add(connectPointSet);
            }
        });
        return clusters;
    }

    /**
     * Topology event listener.
     */
    private class InternalTopologyListener implements TopologyListener {
        @Override
        public void event(TopologyEvent event) {
            if (!isRelevant(event)) {
                return;
            }

            Topology topology = event.subject();
            providerService.topologyChanged(getConnectPoints(topology));
        }

        @Override
        public boolean isRelevant(TopologyEvent event) {
            final boolean[] relevant = {false};
            if (event.type().equals(TopologyEvent.Type.TOPOLOGY_CHANGED)) {
                event.reasons().forEach(event1 -> {
                    // Only LinkEvents are relevant events, ie: DeviceEvents and others are ignored.
                    if (event1 instanceof LinkEvent) {
                        relevant[0] = true;
                        return;
                    }
                });
            }
            return relevant[0];
        }
    }
}
