/*
 * 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.isis.topology.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onlab.util.Bandwidth;
import org.onosproject.isis.controller.IsisController;
import org.onosproject.isis.controller.IsisProcess;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLink;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLinkTed;
import org.onosproject.isis.controller.impl.topology.DefaultIsisRouter;
import org.onosproject.isis.controller.topology.IsisLink;
import org.onosproject.isis.controller.topology.IsisLinkListener;
import org.onosproject.isis.controller.topology.IsisLinkTed;
import org.onosproject.isis.controller.topology.IsisRouter;
import org.onosproject.isis.controller.topology.IsisRouterListener;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.config.basics.BandwidthCapacity;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.link.LinkServiceAdapter;
import org.onosproject.net.provider.ProviderId;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * Test cases for ISIS topology provider.
 */
public class IsisTopologyProviderTest {

    private final IsisTopologyProvider provider = new IsisTopologyProvider();
    private final TestDeviceRegistry nodeRegistry = new TestDeviceRegistry();
    private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
    private final TestController controller = new TestController();
    private final TestLinkService linkService = new TestLinkService();
    private MockNetConfigRegistryAdapter networkConfigService = new MockNetConfigRegistryAdapter();

    @Before
    public void setUp() throws Exception {
        provider.deviceProviderRegistry = nodeRegistry;
        provider.linkProviderRegistry = linkRegistry;
        provider.networkConfigService = networkConfigService;
        provider.controller = controller;
        provider.linkService = linkService;
        provider.activate();
        assertNotNull("provider should be registered", nodeRegistry.provider);
        assertNotNull("listener should be registered", controller.nodeListener);
    }

    @After
    public void tearDown() throws Exception {
        provider.deactivate();
        provider.controller = null;
        provider.deviceProviderRegistry = null;
        provider.networkConfigService = null;
    }

    @Test
    public void triggerProbe() {
        DeviceId deviceId = DeviceId.deviceId("2929.2929.2929.00-00");
        provider.triggerProbe(deviceId);
    }

    @Test
    public void roleChanged() {
        DeviceId deviceId = DeviceId.deviceId("1111.1111.1111.00-00");
        provider.roleChanged(deviceId, MastershipRole.MASTER);
    }

    @Test
    public void changePortState() {
        DeviceId deviceId = DeviceId.deviceId("2222.2222.2222.00-82");
        provider.changePortState(deviceId, PortNumber.portNumber(168430087), false);
    }

    @Test
    public void isReachable() {
        DeviceId deviceId = DeviceId.deviceId("1010.1010.1111.00-22");
        provider.isReachable(deviceId);
    }


    /* Validate node is added to the device validating URI and should get updated properly */
    @Test
    public void isisTopologyProviderTestAddDevice1() {
        int deviceAddCount = 0;
        IsisRouter isisRouter = new DefaultIsisRouter();
        isisRouter.setSystemId("2929.2929.2929.00");
        isisRouter.setNeighborRouterId(Ip4Address.valueOf("10.10.10.1"));
        isisRouter.setInterfaceId(Ip4Address.valueOf("10.10.10.2"));
        isisRouter.setDis(false);

        for (IsisRouterListener l : controller.nodeListener) {
            l.routerAdded(isisRouter);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 1);
            l.routerRemoved(isisRouter);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 0);
        }
    }

    @Test
    public void isisTopologyProviderTestAddDevice2() {
        int deviceAddCount = 0;
        IsisRouter isisRouter = new DefaultIsisRouter();
        isisRouter.setSystemId("7777.7777.7777.00");
        isisRouter.setNeighborRouterId(Ip4Address.valueOf("10.10.10.1"));
        isisRouter.setInterfaceId(Ip4Address.valueOf("10.10.10.7"));
        isisRouter.setDis(false);
        IsisRouter isisRouter1 = new DefaultIsisRouter();
        isisRouter1.setSystemId("1111.1111.1111.00");
        isisRouter1.setNeighborRouterId(Ip4Address.valueOf("10.10.10.7"));
        isisRouter1.setInterfaceId(Ip4Address.valueOf("10.10.10.1"));
        isisRouter1.setDis(true);
        for (IsisRouterListener l : controller.nodeListener) {
            l.routerAdded(isisRouter);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 1);
            l.routerAdded(isisRouter1);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 2);
            l.routerRemoved(isisRouter);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 1);
        }
    }

    @Test
    public void isisTopologyProviderTestAddLink() {
        int deviceAddCount = 0;
        IsisRouter isisRouter = new DefaultIsisRouter();
        isisRouter.setSystemId("7777.7777.7777.00");
        isisRouter.setNeighborRouterId(Ip4Address.valueOf("10.10.10.1"));
        isisRouter.setInterfaceId(Ip4Address.valueOf("10.10.10.7"));
        isisRouter.setDis(false);
        IsisRouter isisRouter1 = new DefaultIsisRouter();
        isisRouter1.setSystemId("1111.1111.1111.00");
        isisRouter1.setNeighborRouterId(Ip4Address.valueOf("10.10.10.7"));
        isisRouter1.setInterfaceId(Ip4Address.valueOf("10.10.10.1"));
        isisRouter1.setDis(true);
        IsisLink isisLink = new DefaultIsisLink();
        isisLink.setRemoteSystemId("7777.7777.7777.00");
        isisLink.setLocalSystemId("1111.1111.1111.00");
        isisLink.setInterfaceIp(Ip4Address.valueOf("10.10.10.1"));
        isisLink.setNeighborIp(Ip4Address.valueOf("10.10.10.7"));
        IsisLinkTed isisLinkTed = new DefaultIsisLinkTed();
        isisLinkTed.setTeDefaultMetric(10);
        isisLinkTed.setAdministrativeGroup(5);
        isisLinkTed.setIpv4InterfaceAddress(Ip4Address.valueOf("10.10.10.1"));
        isisLinkTed.setIpv4NeighborAddress(Ip4Address.valueOf("10.10.10.7"));
        isisLinkTed.setMaximumLinkBandwidth(Bandwidth.bps(0));
        isisLinkTed.setMaximumReservableLinkBandwidth(Bandwidth.bps(1.0));
        List<Bandwidth> unresList = new ArrayList<>();
        unresList.add(Bandwidth.bps(0.0));
        unresList.add(Bandwidth.bps(1.0));
        unresList.add(Bandwidth.bps(2.0));
        unresList.add(Bandwidth.bps(3.0));
        isisLinkTed.setUnreservedBandwidth(unresList);
        isisLink.setLinkTed(isisLinkTed);
        for (IsisRouterListener l : controller.nodeListener) {
            l.routerAdded(isisRouter);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 1);
            l.routerAdded(isisRouter1);
            deviceAddCount = nodeRegistry.connected.size();
            assertTrue(deviceAddCount == 2);
        }
        for (IsisLinkListener l : controller.linkListener) {
            l.addLink(isisLink);
            l.deleteLink(isisLink);

        }
    }


    /* Class implement device test registry */
    private class TestDeviceRegistry implements DeviceProviderRegistry {
        DeviceProvider provider;

        Set<DeviceId> connected = new HashSet<>();

        @Override
        public DeviceProviderService register(DeviceProvider provider) {
            this.provider = provider;
            return new TestProviderService();
        }

        @Override
        public void unregister(DeviceProvider provider) {
        }

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

        private class TestProviderService implements DeviceProviderService {

            @Override
            public DeviceProvider provider() {
                return null;
            }

            @Override
            public void deviceConnected(DeviceId deviceId, DeviceDescription deviceDescription) {

                connected.add(deviceId);

            }

            @Override
            public void deviceDisconnected(DeviceId deviceId) {

                connected.remove(deviceId);
            }


            @Override
            public void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
                // TODO Auto-generated method stub

            }

            @Override
            public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
                // TODO Auto-generated method stub

            }

            @Override
            public void receivedRoleReply(DeviceId deviceId, MastershipRole requested, MastershipRole response) {
                // TODO Auto-generated method stub

            }


            @Override
            public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
                // TODO Auto-generated method stub

            }
        }
    }



    private class TestDeviceService extends DeviceServiceAdapter {
        private DeviceListener listener;

        @Override
        public void addListener(DeviceListener listener) {
            this.listener = listener;
        }

        @Override
        public Iterable<Device> getDevices() {
            return Collections.emptyList();
        }
    }

    private class TestLinkService extends LinkServiceAdapter {
        private LinkListener listener;

        @Override
        public void addListener(LinkListener listener) {
            this.listener = listener;
        }

        @Override
        public Iterable<Link> getLinks() {
            return Collections.emptyList();
        }
    }

    /* Class implement device test registry */
    private class TestLinkRegistry implements LinkProviderRegistry {
        LinkProvider provider;

        Set<DeviceId> connected = new HashSet<>();

        @Override
        public LinkProviderService register(LinkProvider provider) {
            this.provider = provider;
            return new TestLinkProviderService();
        }

        @Override
        public void unregister(LinkProvider provider) {

        }

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

        private class TestLinkProviderService implements LinkProviderService {

            @Override
            public void linkDetected(LinkDescription linkDescription) {

            }

            @Override
            public void linkVanished(LinkDescription linkDescription) {

            }

            @Override
            public void linksVanished(ConnectPoint connectPoint) {

            }

            @Override
            public void linksVanished(DeviceId deviceId) {

            }

            @Override
            public LinkProvider provider() {
                return null;
            }
        }
    }

    /* class implement test controller */
    private class TestController implements IsisController {
        protected Set<IsisRouterListener> nodeListener = new CopyOnWriteArraySet<>();
        protected Set<IsisLinkListener> linkListener = new CopyOnWriteArraySet<>();

        @Override
        public void addRouterListener(IsisRouterListener nodeListener) {
            this.nodeListener.add(nodeListener);
        }

        @Override
        public void removeRouterListener(IsisRouterListener nodeListener) {
            this.nodeListener.remove(nodeListener);
        }

        @Override
        public void addLinkListener(IsisLinkListener listener) {
            this.linkListener.add(listener);
        }

        @Override
        public void removeLinkListener(IsisLinkListener listener) {
            this.linkListener.remove(listener);
        }

        @Override
        public void updateConfig(JsonNode processesNode) {

        }

        @Override
        public List<IsisProcess> allConfiguredProcesses() {
            return null;
        }

        @Override
        public Set<IsisRouterListener> listener() {
            return null;
        }

        @Override
        public Set<IsisLinkListener> linkListener() {
            return null;
        }

    }

    /* Mock test for device service */
    private class MockNetConfigRegistryAdapter extends NetworkConfigRegistryAdapter {
        private ConfigFactory cfgFactory;
        private Map<ConnectPoint, BandwidthCapacity> classConfig = new HashMap<>();

        @Override
        public void registerConfigFactory(ConfigFactory configFactory) {
            cfgFactory = configFactory;
        }

        @Override
        public void unregisterConfigFactory(ConfigFactory configFactory) {
            cfgFactory = null;
        }

        @Override
        public <S, C extends Config<S>> C addConfig(S subject, Class<C> configClass) {
            if (configClass == BandwidthCapacity.class) {
                BandwidthCapacity devCap = new BandwidthCapacity();
                classConfig.put((ConnectPoint) subject, devCap);

                JsonNode node = new ObjectNode(new MockJsonNode());
                ObjectMapper mapper = new ObjectMapper();
                ConfigApplyDelegate delegate = new InternalApplyDelegate();
                devCap.init((ConnectPoint) subject, null, node, mapper, delegate);
                return (C) devCap;
            }

            return null;
        }

        @Override
        public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
            classConfig.remove(subject);
        }

        @Override
        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
            if (configClass == BandwidthCapacity.class) {
                return (C) classConfig.get(subject);
            }
            return null;
        }

        private class MockJsonNode extends JsonNodeFactory {
        }

        // Auxiliary delegate to receive notifications about changes applied to
        // the network configuration - by the apps.
        private class InternalApplyDelegate implements ConfigApplyDelegate {
            @Override
            public void onApply(Config config) {
            }
        }
    }
}