/*
 * 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.provider.linkdiscovery.impl;

import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ComponentContextAdapter;
import org.onlab.packet.ChassisId;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.AbstractProjectableModel;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Annotations;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.LinkDiscovery;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.driver.Behaviour;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverAdapter;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverServiceAdapter;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProviderRegistryAdapter;
import org.onosproject.net.link.LinkProviderServiceAdapter;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.provider.ProviderId;

import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;
import static org.onlab.junit.TestTools.assertAfter;
import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.APP_NAME;
import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.SCHEME_NAME;

/**
 * Test for polling mechanism of the NetconfLinkProvider.
 */
public class LinkDiscoveryProviderTest {

    private static final ComponentContextAdapter CONTEXT =
            new ComponentContextAdapter() {
                @Override
                public Dictionary getProperties() {
                    Hashtable<String, Integer> props = new Hashtable<>();
                    props.put("linkPollFrequencySeconds", 2);
                    props.put("linkPollDelaySeconds", 1);
                    props.put("linkDiscoveryTimeoutSeconds", 1);
                    return props;
                }
            };
    // Network Mocks
    private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("netconf:1.1.1.1");
    private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("netconf:1.1.1.2");
    private static final ConnectPoint CP11 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(1));
    private static final ConnectPoint CP12 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(2));
    private static final ConnectPoint CP13 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(3));
    private static final ConnectPoint CP14 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(4));
    private static final ConnectPoint CP21 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(1));
    private static final ConnectPoint CP22 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(2));
    private static final ConnectPoint CP23 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(3));
    private static final ConnectPoint CP24 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(4));
    private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
            .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
    private static final DefaultAnnotations LINK_ANNOTATIONS = DefaultAnnotations.builder()
            .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
    private static final LinkKey LINKKEY1 = LinkKey.linkKey(CP11, CP21);
    private static final LinkDescription LINK1 = new DefaultLinkDescription(CP11, CP21,
                                                                            Link.Type.DIRECT,
                                                                            LINK_ANNOTATIONS);
    private static final LinkKey LINKKEY2 = LinkKey.linkKey(CP12, CP22);
    private static final LinkDescription LINK2 = new DefaultLinkDescription(CP12, CP22,
                                                                            Link.Type.DIRECT,
                                                                            LINK_ANNOTATIONS);
    private static final LinkKey LINKKEY3 = LinkKey.linkKey(CP13, CP23);
    private static final LinkDescription LINK3 = new DefaultLinkDescription(CP13, CP23,
                                                                            Link.Type.DIRECT,
                                                                            DefaultAnnotations.builder()
                                                                                    .build());
    private static final LinkKey LINKKEY4 = LinkKey.linkKey(CP14, CP24);
    private static final LinkDescription LINK4 = new DefaultLinkDescription(CP14, CP24,
                                                                            Link.Type.DIRECT,
                                                                            DefaultAnnotations.builder().build());
    //Service Mocks
    private final MockDeviceService deviceService = new MockDeviceService();
    private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
    private final MastershipService mastershipService = new MockMastershipService();
    private final MockLinkService linkService = new MockLinkService();
    private final Driver driver = new MockDriver();
    //Provider related classes
    private LinkProviderServiceAdapter providerService;
    private CoreService coreService;
    private LinkDiscoveryProvider provider = new LinkDiscoveryProvider();
    private final Device device1 = new MockDevice(provider.id(), DEVICE_ID_1, Device.Type.SWITCH,
                                                  "foo.inc", "0", "0", "0", new ChassisId(),
                                                  DEVICE_ANNOTATIONS);
    private Set<DeviceListener> deviceListeners = new HashSet<>();
    private ApplicationId appId =
            new DefaultApplicationId(100, APP_NAME);
    private TestLink testLink = new TestLink();

    @Before
    public void setUp() {
        coreService = createMock(CoreService.class);
        expect(coreService.registerApplication(appId.name()))
                .andReturn(appId).anyTimes();
        replay(coreService);
        provider.coreService = coreService;
        provider.providerRegistry = linkRegistry;
        provider.deviceService = deviceService;
        provider.mastershipService = mastershipService;
        provider.linkService = linkService;
        provider.cfgService = new ComponentConfigAdapter();
        AbstractProjectableModel.setDriverService(null, new DriverServiceAdapter());
        provider.activate(null);
        providerService = linkRegistry.registeredProvider();
    }

    @Test
    public void activate() throws Exception {
        assertTrue("Provider should be registered", linkRegistry.getProviders().contains(provider.id()));
        assertEquals("Device service should be registered", provider.deviceService, deviceService);
        assertEquals("Device listener should be added", 1, deviceListeners.size());
        assertNotNull("Registration expected", providerService);
        assertEquals("Incorrect  provider", provider, providerService.provider());
        assertFalse("Executor should be running", provider.executor.isShutdown());
        assertFalse("Executor should be running", provider.executor.isTerminated());
        assertEquals("Incorrect polling frequency, should be default", 10,
                     provider.linkPollFrequencySeconds);
        assertEquals("Incorrect polling delay , should be default", 20,
                     provider.linkPollDelaySeconds);
        assertEquals("Incorrect polling discovery delay , should be default", 300,
                     provider.linkDiscoveryTimeoutSeconds);
    }

    @Test
    public void modified() throws Exception {
        provider.modified(CONTEXT);
        assertEquals("Incorrect polling frequency, should be default", 2,
                     provider.linkPollFrequencySeconds);
        assertEquals("Incorrect polling delay , should be default", 1,
                     provider.linkPollDelaySeconds);
        assertEquals("Incorrect polling discovery delay , should be default", 1,
                     provider.linkDiscoveryTimeoutSeconds);

    }


    @Test
    public void deactivate() throws Exception {
        provider.deactivate();
        assertEquals("Device listener should be removed", 0, deviceListeners.size());
        assertFalse("Provider should not be registered", linkRegistry.getProviders().contains(provider.id()));
        assertTrue(provider.executor.isShutdown());
        assertNull(provider.providerService);
    }


    @Test
    public void linksTestForStoredDevice() {
        provider.modified(CONTEXT);
        providerService.discoveredLinkDescriptions().put(LINKKEY1, LINK1);
        providerService.discoveredLinkDescriptions().put(LINKKEY2, LINK2);
        providerService.discoveredLinkDescriptions().put(LINKKEY4, LINK4);
        testLink.addLinkDesc(LINK2);
        testLink.addLinkDesc(LINK3);
        assertAfter(1100, () -> {
            assertEquals("Total number of link must be 3", 3, providerService.discoveredLinkDescriptions().size());
            assertFalse("Link1 should be removed",
                        providerService.discoveredLinkDescriptions().containsKey(LINKKEY1));
            assertTrue("Link2 should be present",
                       providerService.discoveredLinkDescriptions().containsKey(LINKKEY2));
            assertTrue("Link3 should be added",
                       providerService.discoveredLinkDescriptions().containsKey(LINKKEY3));
            assertEquals("Link3 should be annotated", SCHEME_NAME.toUpperCase(),
                         providerService.discoveredLinkDescriptions()
                    .get(LINKKEY3).annotations().value(AnnotationKeys.PROTOCOL));
            assertTrue("Link4 should be present because it is not related to the LinkDiscovery",
                       providerService.discoveredLinkDescriptions().containsKey(LINKKEY4));

        });
        clear();
    }

    private void clear() {
        testLink.clearLinkDesc();
        providerService.discoveredLinkDescriptions().clear();
        providerService.discoveredLinks().clear();
    }

    private class MockDeviceService extends DeviceServiceAdapter {

        @Override
        public Iterable<Device> getAvailableDevices() {
            return ImmutableSet.of(device1);
        }

        @Override
        public Device getDevice(DeviceId deviceId) {
            return device1;
        }

        @Override
        public void addListener(DeviceListener listener) {
            deviceListeners.add(listener);
        }

        @Override
        public void removeListener(DeviceListener listener) {
            deviceListeners.remove(listener);
        }
    }

    private class MockMastershipService extends MastershipServiceAdapter {

        @Override
        public boolean isLocalMaster(DeviceId deviceId) {
            return true;
        }
    }

    private class MockLinkService extends LinkServiceAdapter {
        @Override
        public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
            Set<Link> links = new HashSet<>();
            providerService.discoveredLinkDescriptions().values()
                    .forEach(x -> links.add(DefaultLink.builder()
                                                    .providerId(provider.id())
                                                    .src(x.src())
                                                    .dst(x.dst())
                                                    .type(x.type())
                                                    .isExpected(x.isExpected())
                                                    .annotations(x.annotations()).build()));
            return ImmutableSet.copyOf(links);
        }
    }

    private class MockDevice extends DefaultDevice {

        public MockDevice(ProviderId providerId, DeviceId id, Type type,
                          String manufacturer, String hwVersion, String swVersion,
                          String serialNumber, ChassisId chassisId, Annotations... annotations) {
            super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
                  chassisId, annotations);
        }

        @Override
        protected Driver locateDriver() {
            return driver;
        }

        @Override
        public Driver driver() {
            return driver;
        }
    }

    private class MockDriver extends DriverAdapter {
        @Override
        public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {

            return (T) testLink;
        }
    }

    private class TestLink extends AbstractHandlerBehaviour implements LinkDiscovery {
        Set<LinkDescription> linkDescriptions = new HashSet<>();

        @Override
        public Set<LinkDescription> getLinks() {
            return ImmutableSet.copyOf(linkDescriptions);
        }

        private void addLinkDesc(LinkDescription link) {
            linkDescriptions.add(link);
        }

        private void clearLinkDesc() {
            linkDescriptions.clear();
        }

    }
}
