package org.onlab.onos.net.topology.impl;

import com.google.common.collect.ImmutableSet;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.onos.event.Event;
import org.onlab.onos.event.impl.TestEventDispatcher;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.device.DeviceEvent;
import org.onlab.onos.net.device.impl.DeviceManager;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.link.impl.LinkManager;
import org.onlab.onos.net.provider.AbstractProviderService;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.net.topology.GraphDescription;
import org.onlab.onos.net.topology.TopologyProvider;
import org.onlab.onos.net.topology.TopologyProviderRegistry;
import org.onlab.onos.net.topology.TopologyProviderService;

import java.util.List;
import java.util.Set;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import static org.onlab.onos.net.NetTestTools.device;
import static org.onlab.onos.net.NetTestTools.link;
import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_ADDED;
import static org.onlab.onos.net.link.LinkEvent.Type.LINK_ADDED;

/**
 * Test of the default topology provider implementation.
 */
public class DefaultTopologyProviderTest {

    private DefaultTopologyProvider provider = new DefaultTopologyProvider();
    private TestTopoRegistry topologyService = new TestTopoRegistry();
    private TestDeviceService deviceService = new TestDeviceService();
    private TestLinkService linkService = new TestLinkService();
    private TestTopoProviderService providerService;

    // phase corresponds to number of topologyChanged called
    private Phaser topologyChangedCounts = new Phaser(1);

    @Before
    public void setUp() {
        provider.deviceService = deviceService;
        provider.linkService = linkService;
        provider.providerRegistry = topologyService;
        provider.activate();
    }

    @After
    public void tearDown() {
        provider.deactivate();
        provider.providerRegistry = null;
        provider.deviceService = null;
        provider.linkService = null;
    }

    private void validateSubmission() {
        assertNotNull("registration expected", providerService);
        assertEquals("incorrect provider", provider, providerService.provider());
        assertNotNull("topo change should be submitted", providerService.graphDesc);
        assertEquals("incorrect vertex count", 6, providerService.graphDesc.vertexes().size());
        assertEquals("incorrect edge count", 10, providerService.graphDesc.edges().size());
    }

    @Test
    public void basics() throws InterruptedException, TimeoutException {
        assertEquals(1, topologyChangedCounts.awaitAdvanceInterruptibly(0, 1, TimeUnit.SECONDS));
        validateSubmission();
    }

    @Test
    public void eventDriven() throws InterruptedException, TimeoutException {
        assertEquals(1, topologyChangedCounts.awaitAdvanceInterruptibly(0, 1, TimeUnit.SECONDS));
        validateSubmission();

        deviceService.post(new DeviceEvent(DEVICE_ADDED, device("z"), null));
        linkService.post(new LinkEvent(LINK_ADDED, link("z", 1, "a", 4)));
        assertThat(topologyChangedCounts.awaitAdvanceInterruptibly(1, 1, TimeUnit.SECONDS),
                is(greaterThanOrEqualTo(2)));
        // Note: posting event, to trigger topologyChanged call,
        // but dummy topology will not change.
        validateSubmission();
    }


    private class TestTopoRegistry implements TopologyProviderRegistry {

        @Override
        public TopologyProviderService register(TopologyProvider provider) {
            providerService = new TestTopoProviderService(provider);
            return providerService;
        }

        @Override
        public void unregister(TopologyProvider provider) {
        }

        @Override
        public Set<ProviderId> getProviders() {
            return null;
        }
    }

    private class TestTopoProviderService
            extends AbstractProviderService<TopologyProvider>
            implements TopologyProviderService {
        GraphDescription graphDesc;

        protected TestTopoProviderService(TopologyProvider provider) {
            super(provider);
        }

        @Override
        public void topologyChanged(GraphDescription graphDescription, List<Event> reasons) {
            graphDesc = graphDescription;
            topologyChangedCounts.arrive();
        }
    }

    private class TestDeviceService extends DeviceManager {
        TestDeviceService() {
            eventDispatcher = new TestEventDispatcher();
            eventDispatcher.addSink(DeviceEvent.class, listenerRegistry);
        }

        @Override
        public Iterable<Device> getDevices() {
            return ImmutableSet.of(device("a"), device("b"),
                                   device("c"), device("d"),
                                   device("e"), device("f"));
        }

        void post(DeviceEvent event) {
            eventDispatcher.post(event);
        }
    }

    private class TestLinkService extends LinkManager {
        TestLinkService() {
            eventDispatcher = new TestEventDispatcher();
            eventDispatcher.addSink(LinkEvent.class, listenerRegistry);
        }

        @Override
        public Iterable<Link> getLinks() {
            return ImmutableSet.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));
        }

        void post(LinkEvent event) {
            eventDispatcher.post(event);
        }
    }
}
