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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.incubator.net.config.basics.ConfigException;
import org.onosproject.net.AbstractProjectableModel;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigRegistryAdapter;
import org.onosproject.net.config.basics.BasicDeviceConfig;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderRegistryAdapter;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceProviderServiceAdapter;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.device.DeviceStore;
import org.onosproject.net.device.DeviceStoreAdapter;
import org.onosproject.net.driver.DriverServiceAdapter;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.snmp.SnmpController;

import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import static org.junit.Assert.*;
import static org.onlab.junit.TestTools.assertAfter;

/**
 * Testing class for SnmpDeviceProvider.
 */
public class SnmpDeviceProviderTest {

    public static final int TEST_DURATION = 1500;
    public static final int DELAY = 500;
    private final SnmpDeviceProvider provider = new SnmpDeviceProvider();
    private final SnmpController controller = new SnmpControllerAdapter();
    private final DeviceProviderRegistry providerRegistry = new MockDeviceProviderRegistry();
    private final DeviceService deviceService = new MockDeviceService();
    private final NetworkConfigRegistry netCfgService = new MockNetworkConfigRegistry();
    private final DeviceStore deviceStore = new MockDeviceStore();
    protected CoreService coreService = new MockCoreService();
    private final DeviceProviderService deviceProviderService = new MockDeviceProviderService();
    private final TestApplicationId applicationId = new TestApplicationId("TestAppId");
    private final SnmpProviderConfig snmpProviderConfig = new MockSnmpProviderConfig();
    private final DeviceId deviceId = DeviceId.deviceId("snmp:1.1.1.1:1");
    private final DeviceId wrongDeviceId = DeviceId.deviceId("snmp:2.2.2.2:2");
    private final Set<ConfigFactory> cfgFactories = new HashSet<>();
    private final Set<NetworkConfigListener> netCfgListeners = new HashSet<>();
    private final NetworkConfigEvent deviceAddedEvent =
            new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
                                   null, SnmpProviderConfig.class);
    private final NetworkConfigEvent deviceAddedIrrelevantEvent =
            new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
                                   null, BasicDeviceConfig.class);
    private final NetworkConfigEvent deviceAddedNewEvent =
            new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
                                   deviceId, SnmpDeviceConfig.class);
    private final SnmpDeviceConfig config = new SnmpDeviceConfig();
    //Testing Files
    private final InputStream jsonStream = SnmpDeviceProviderTest.class
            .getResourceAsStream("/device.json");
    private final ObjectMapper mapper = new ObjectMapper();
    private final String KEY = "snmp";


    @Before
    public void setUp() throws Exception {
        provider.controller = controller;
        provider.providerRegistry = providerRegistry;
        provider.deviceService = deviceService;
        provider.netCfgService = netCfgService;
        provider.deviceStore = deviceStore;
        provider.coreService = coreService;
        JsonNode jsonNode = mapper.readTree(jsonStream);
        ConfigApplyDelegate delegate = new MockDelegate();
        config.init(deviceId, KEY, jsonNode, mapper, delegate);
        provider.activate(null);
    }

    @Test
    public void testActivate() {
        assertEquals("Incorrect provider service", deviceProviderService, provider.providerService);
        assertEquals("Incorrect application id", applicationId, provider.appId);
        assertTrue("Incorrect config factories", cfgFactories.containsAll(provider.factories));
        assertTrue("Incorrect network config listener", netCfgListeners.contains(provider.cfgLister));


    }

    @Test
    public void testDeactivate() {
        this.addDevice();
        provider.deactivate(null);
        assertAfter(DELAY, TEST_DURATION, () ->
                assertNull("Device should be removed", controller.getDevice(deviceId)));
        assertTrue("Network config factory not removed", cfgFactories.isEmpty());
        assertFalse("Network config listener not removed", netCfgListeners.contains(provider.cfgLister));
        assertFalse("Provider not unregistered", providerRegistry.getProviders().contains(provider.id()));
        assertNull("Provider registry not removed", provider.providerService);
    }

    @Test
    public void eventNotRelevant() {
        assertFalse("Event should not be relevant", provider.cfgLister.isRelevant(deviceAddedIrrelevantEvent));
        assertFalse("Device should not be reachable", provider.isReachable(wrongDeviceId));
    }

    @Test
    public void addDevice() {
        assertTrue("Event should be relevant", provider.cfgLister.isRelevant(deviceAddedEvent));
        provider.cfgLister.event(deviceAddedEvent);
        AbstractProjectableModel.setDriverService(null, new MockDriverService());
        //FIXME this needs sleep
        assertAfter(DELAY, TEST_DURATION, () ->
                assertNotNull("Device should be added to controller", controller.getDevice(deviceId)));
        assertTrue("Device should be reachable", provider.isReachable(deviceId));
    }

    @Test
    public void addDeviceNew() {
        assertTrue("Event should be relevant", provider.cfgLister.isRelevant(deviceAddedNewEvent));
        provider.cfgLister.event(deviceAddedNewEvent);
        AbstractProjectableModel.setDriverService(null, new MockDriverService());
        //FIXME this needs sleep
        assertAfter(DELAY, TEST_DURATION, () ->
                assertNotNull("Device should be added to controller", controller.getDevice(deviceId)));
        assertTrue("Device should be reachable", provider.isReachable(deviceId));
    }

    private class MockDeviceProviderRegistry extends DeviceProviderRegistryAdapter {

        Set<ProviderId> providers = new HashSet<>();

        @Override
        public DeviceProviderService register(DeviceProvider provider) {
            providers.add(provider.id());
            return deviceProviderService;
        }

        @Override
        public void unregister(DeviceProvider provider) {
            providers.remove(provider.id());
        }

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

    }

    private class MockDeviceService extends DeviceServiceAdapter {
        @Override
        public Device getDevice(DeviceId deviceId) {
            return deviceStore.getDevice(deviceId);
        }
    }

    private class MockNetworkConfigRegistry extends NetworkConfigRegistryAdapter {

        @Override
        public void registerConfigFactory(ConfigFactory configFactory) {
            cfgFactories.add(configFactory);
        }

        @Override
        public void unregisterConfigFactory(ConfigFactory configFactory) {
            cfgFactories.remove(configFactory);
        }

        @Override
        public void addListener(NetworkConfigListener listener) {
            netCfgListeners.add(listener);
        }

        @Override
        public void removeListener(NetworkConfigListener listener) {
            netCfgListeners.remove(listener);
        }


        @Override
        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
            if (configClass.equals(SnmpProviderConfig.class)) {
                return (C) snmpProviderConfig;
            } else if (configClass.equals(SnmpDeviceConfig.class)) {
                return (C) config;
            } else {
                return (C) new BasicDeviceConfig();
            }
        }

        @Override
        public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subjectClass, Class<C> configClass) {
            return ImmutableSet.of((S) deviceId);
        }
    }

    private class MockDeviceStore extends DeviceStoreAdapter {
        protected HashMap<DeviceId, Device> devices = new HashMap<>();

        @Override
        public DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId,
                                                DeviceDescription desc) {

            devices.put(deviceId, new DefaultDevice(providerId, deviceId, desc.type(),
                                                    desc.manufacturer(), desc.hwVersion(),
                                                    desc.swVersion(), desc.serialNumber(),
                                                    desc.chassisId(), DefaultAnnotations.builder().build()));
            return null;
        }

        @Override
        public Device getDevice(DeviceId deviceId) {
            return devices.get(deviceId);
        }

    }

    private class MockCoreService extends CoreServiceAdapter {
        @Override
        public ApplicationId registerApplication(String name) {
            return applicationId;
        }
    }

    private class MockDeviceProviderService extends DeviceProviderServiceAdapter {
        DeviceStore store = deviceStore;

        @Override
        public void deviceConnected(DeviceId deviceId, DeviceDescription desc) {
            store.createOrUpdateDevice(ProviderId.NONE, deviceId, desc);
        }
    }

    private class MockSnmpProviderConfig extends SnmpProviderConfig {
        protected SnmpDeviceInfo deviceInfo = new SnmpDeviceInfo(IpAddress.valueOf("1.1.1.1"), 1, "test", "test");

        @Override
        public Set<SnmpProviderConfig.SnmpDeviceInfo> getDevicesInfo() throws ConfigException {
            return ImmutableSet.of(deviceInfo);
        }

    }

    private class MockDriverService extends DriverServiceAdapter {

    }

    private class MockDelegate implements ConfigApplyDelegate {
        @Override
        public void onApply(Config config) {

        }
    }
}