/*
 * Copyright 2014-2015 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.net.topology.impl;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.event.Event;
import org.onosproject.event.impl.TestEventDispatcher;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.Link;
import org.onosproject.net.Path;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.DefaultGraphDescription;
import org.onosproject.net.topology.GraphDescription;
import org.onosproject.net.topology.LinkWeight;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyCluster;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyGraph;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyProvider;
import org.onosproject.net.topology.TopologyProviderRegistry;
import org.onosproject.net.topology.TopologyProviderService;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.store.trivial.impl.SimpleTopologyStore;

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

import static com.google.common.collect.ImmutableSet.of;
import static org.junit.Assert.*;
import static org.onosproject.net.NetTestTools.*;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.topology.ClusterId.clusterId;
import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;

/**
 * Test of the topology subsystem.
 */
public class TopologyManagerTest {

    private static final ProviderId PID = new ProviderId("of", "foo");

    private TopologyManager mgr;

    protected TopologyService service;
    protected TopologyProviderRegistry registry;
    protected TopologyProviderService providerService;
    protected TestProvider provider;
    protected TestListener listener = new TestListener();

    @Before
    public void setUp() {
        mgr = new TopologyManager();
        service = mgr;
        registry = mgr;

        mgr.store = new SimpleTopologyStore();
        mgr.eventDispatcher = new TestEventDispatcher();
        mgr.activate();

        service.addListener(listener);

        provider = new TestProvider();
        providerService = registry.register(provider);

        assertTrue("provider should be registered",
                   registry.getProviders().contains(provider.id()));
    }

    @After
    public void tearDown() {
        mgr.deactivate();
        service.removeListener(listener);
    }

    @Test
    public void basics() {
        Topology topology = service.currentTopology();
        assertNull("no topo expected", topology);
        submitTopologyGraph();
        validateEvents(TOPOLOGY_CHANGED);
        topology = service.currentTopology();
        assertTrue("should be latest", service.isLatest(topology));

        submitTopologyGraph();
        validateEvents(TOPOLOGY_CHANGED);
        assertFalse("should be latest", service.isLatest(topology));
    }

    private void submitTopologyGraph() {
        Set<Device> devices = of(device("a"), device("b"),
                                 device("c"), device("d"),
                                 device("e"), device("f"));
        Set<Link> links = of(link("a", 1, "b", 1), link("b", 1, "a", 1),
                             link("b", 2, "c", 1), link("c", 1, "b", 2),
                             link("c", 2, "d", 1), link("d", 1, "c", 2),
                             link("d", 2, "a", 2), link("a", 2, "d", 2),
                             link("e", 1, "f", 1), link("f", 1, "e", 1));
        GraphDescription data = new DefaultGraphDescription(4321L, devices, links);
        providerService.topologyChanged(data, null);
    }

    @Test
    public void clusters() {
        submitTopologyGraph();
        Topology topology = service.currentTopology();
        assertNotNull("topo expected", topology);
        assertEquals("wrong cluster count", 2, topology.clusterCount());
        assertEquals("wrong device count", 6, topology.deviceCount());
        assertEquals("wrong link count", 10, topology.linkCount());

        assertEquals("wrong cluster count", 2, service.getClusters(topology).size());

        TopologyCluster cluster = service.getCluster(topology, clusterId(0));
        assertEquals("wrong device count", 4, cluster.deviceCount());
        assertEquals("wrong device count", 4, service.getClusterDevices(topology, cluster).size());
        assertEquals("wrong link count", 8, cluster.linkCount());
        assertEquals("wrong link count", 8, service.getClusterLinks(topology, cluster).size());
    }

    @Test
    public void structure() {
        submitTopologyGraph();
        Topology topology = service.currentTopology();

        assertTrue("should be infrastructure point",
                   service.isInfrastructure(topology, new ConnectPoint(did("a"), portNumber(1))));
        assertFalse("should not be infrastructure point",
                    service.isInfrastructure(topology, new ConnectPoint(did("a"), portNumber(3))));

        assertTrue("should be broadcast point",
                   service.isBroadcastPoint(topology, new ConnectPoint(did("a"), portNumber(3))));
    }

    @Test
    public void graph() {
        submitTopologyGraph();
        Topology topology = service.currentTopology();
        TopologyGraph graph = service.getGraph(topology);
        assertEquals("wrong vertex count", 6, graph.getVertexes().size());
        assertEquals("wrong edge count", 10, graph.getEdges().size());
    }

    @Test
    public void precomputedPath() {
        submitTopologyGraph();
        Topology topology = service.currentTopology();
        Set<Path> paths = service.getPaths(topology, did("a"), did("c"));
        assertEquals("wrong path count", 2, paths.size());
        Path path = paths.iterator().next();
        assertEquals("wrong path length", 2, path.links().size());
        assertEquals("wrong path cost", 2, path.cost(), 0.01);
    }

    @Test
    public void onDemandPath() {
        submitTopologyGraph();
        Topology topology = service.currentTopology();
        LinkWeight weight = edge -> 3.3;

        Set<Path> paths = service.getPaths(topology, did("a"), did("c"), weight);
        assertEquals("wrong path count", 2, paths.size());
        Path path = paths.iterator().next();
        assertEquals("wrong path length", 2, path.links().size());
        assertEquals("wrong path cost", 6.6, path.cost(), 0.01);
    }

    protected void validateEvents(Enum... types) {
        int i = 0;
        assertEquals("wrong events received", types.length, listener.events.size());
        for (Event event : listener.events) {
            assertEquals("incorrect event type", types[i], event.type());
            i++;
        }
        listener.events.clear();
    }

    private class TestProvider extends AbstractProvider implements TopologyProvider {
        public TestProvider() {
            super(PID);
        }

        @Override
        public void triggerRecompute() {
        }
    }

    private static class TestListener implements TopologyListener {
        final List<TopologyEvent> events = new ArrayList<>();

        @Override
        public void event(TopologyEvent event) {
            events.add(event);
        }
    }

}
