/*
 * Copyright 2015-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.google.common.collect.ImmutableList;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.ChassisId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.config.basics.ConfigException;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
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.basics.SubjectFactories;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.DeviceStore;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.snmp.SnmpController;
import org.onosproject.snmp.SnmpDevice;
import org.onosproject.snmp.ctl.DefaultSnmpDevice;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;

import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider which will try to fetch the details of SNMP devices from the core and run a capability discovery on each of
 * the device.
 */
@Component(immediate = true)
public class SnmpDeviceProvider extends AbstractProvider
        implements DeviceProvider {

    private final Logger log = getLogger(SnmpDeviceProvider.class);

    private static final String UNKNOWN = "unknown";
    private static final String APP_NAME = "org.onosproject.snmp";
    protected static final String SCHEME = "snmp";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected SnmpController controller;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceProviderRegistry providerRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceStore deviceStore;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigRegistry netCfgService;

    protected DeviceProviderService providerService;

    protected ApplicationId appId;

    private final ExecutorService deviceBuilderExecutor = Executors
            .newFixedThreadPool(5, groupedThreads("onos/snmp", "device-creator", log));

    protected final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();


    protected final List<ConfigFactory> factories = ImmutableList.of(
            new ConfigFactory<ApplicationId, SnmpProviderConfig>(APP_SUBJECT_FACTORY,
                                                                 SnmpProviderConfig.class,
                                                                 "snmp_devices",
                                                                 true) {
                @Override
                public SnmpProviderConfig createConfig() {
                    return new SnmpProviderConfig();
                }
            },
            new ConfigFactory<DeviceId, SnmpDeviceConfig>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
                                                          SnmpDeviceConfig.class,
                                                          SCHEME) {
                @Override
                public SnmpDeviceConfig createConfig() {
                    return new SnmpDeviceConfig();
                }
            });


    /**
     * Creates a provider with the supplier identifier.
     */
    public SnmpDeviceProvider() {
        super(new ProviderId("snmp", "org.onosproject.provider.device"));
        //FIXME multiple type of SNMP sessions
    }

    @Activate
    public void activate(ComponentContext context) {

        providerService = providerRegistry.register(this);
        appId = coreService.registerApplication(APP_NAME);
        factories.forEach(netCfgService::registerConfigFactory);
        netCfgService.addListener(cfgLister);
        connectDevices();
        addOrRemoveDevicesConfig();
        modified(context);
        log.info("Started");
    }

    @Deactivate
    public void deactivate(ComponentContext context) {

        try {
            controller.getDevices().forEach(device -> {
                deviceBuilderExecutor.execute(new DeviceFactory(device, false));
            });
            deviceBuilderExecutor.awaitTermination(1000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("Device builder did not terminate");
        }
        deviceBuilderExecutor.shutdownNow();
        factories.forEach(netCfgService::unregisterConfigFactory);
        netCfgService.removeListener(cfgLister);
        providerRegistry.unregister(this);
        providerService = null;
        log.info("Stopped");
    }

    @Modified
    public void modified(ComponentContext context) {
        log.info("Modified");
    }

    //Old method to register devices provided via net-cfg under apps/snmp/ tree
    private void addOrRemoveDevicesConfig() {
        SnmpProviderConfig cfg = netCfgService.getConfig(appId, SnmpProviderConfig.class);
        if (cfg != null) {
            try {
                cfg.getDevicesInfo().forEach(info -> {
                    buildDevice(new DefaultSnmpDevice(info.ip().toString(),
                                                      info.port(), info.username(),
                                                      info.password()));

                });
            } catch (ConfigException e) {
                log.error("Cannot read config error " + e);
            }
        }
    }

    //Method to register devices provided via net-cfg under devices/ tree
    private void connectDevices() {
        Set<DeviceId> deviceSubjects =
                netCfgService.getSubjects(DeviceId.class, SnmpDeviceConfig.class);
        deviceSubjects.forEach(deviceId -> {
            SnmpDeviceConfig config =
                    netCfgService.getConfig(deviceId, SnmpDeviceConfig.class);
            buildDevice(new DefaultSnmpDevice(config.ip().toString(),
                                              config.port(), config.username(), config.password()));
        });
    }

    private void buildDevice(SnmpDevice device) {
        if (device != null) {
            log.debug("Device Detail:host={}, port={}, state={}",
                      device.getSnmpHost(),
                      device.getSnmpPort(),
                      device.isReachable());
            if (device.isReachable()) {
                deviceBuilderExecutor.execute(new DeviceFactory(device, true));
            } else {
                deviceBuilderExecutor.execute(new DeviceFactory(device, false));
            }
        }
    }

    @Override
    public void triggerProbe(DeviceId deviceId) {
        // TODO SNMP devices should be polled at scheduled intervals to retrieve their
        // reachability status and other details e.g.swVersion, serialNumber,chassis,
    }

    @Override
    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
        // TODO Implement Masterhsip Service
    }

    @Override
    public boolean isReachable(DeviceId deviceId) {
        SnmpDevice snmpDevice = controller.getDevice(deviceId);
        if (snmpDevice == null) {
            log.warn("BAD REQUEST: the requested device id: "
                             + deviceId.toString()
                             + "  is not associated to any SNMP Device");
            return false;
        }
        return snmpDevice.isReachable();
    }

    /**
     * This class is intended to add or remove Configured SNMP Devices. Functionality relies on 'createFlag' and
     * 'SnmpDevice' content. The functionality runs as a thread and depending on the 'createFlag' value it will create
     * or remove Device entry from the core.
     */
    //FIXME consider rework.
    private class DeviceFactory implements Runnable {

        private SnmpDevice device;
        private boolean createFlag;

        public DeviceFactory(SnmpDevice device, boolean createFlag) {
            this.device = device;
            this.createFlag = createFlag;
        }

        @Override
        public void run() {
            if (createFlag) {
                log.debug("Trying to create Device Info on ONOS core");
                advertiseDevices();
            } else {
                log.debug("Trying to remove Device Info on ONOS core");
                removeDevices();
            }
        }

        /**
         * For each SNMP Device, remove the entry from the device store.
         */
        private void removeDevices() {
            if (device == null) {
                log.warn("The Request SNMP Device is null, cannot proceed further");
                return;
            }
            DeviceId did = device.deviceId();
            if (controller.getDevice(did) == null) {
                log.error("BAD Request: 'Currently device is not discovered, "
                                  + "so cannot remove/disconnect the device: "
                                  + device.deviceInfo() + "'");
                return;
            }
            providerService.deviceDisconnected(did);
            device.disconnect();
            controller.removeDevice(did);
        }

        /**
         * Initialize SNMP Device object, and notify core saying device connected.
         */
        private void advertiseDevices() {
            try {
                if (device == null) {
                    log.warn("The Request SNMP Device is null, cannot proceed further");
                    return;
                }
                DeviceId did = device.deviceId();
                ChassisId cid = new ChassisId();

                SparseAnnotations annotations = DefaultAnnotations.builder()
                        .set(AnnotationKeys.PROTOCOL, SCHEME.toUpperCase())
                        .build();

                DeviceDescription desc = new DefaultDeviceDescription(
                        did.uri(), Device.Type.OTHER, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN, cid, annotations);

                log.debug("Persisting Device " + did.uri().toString());

                controller.addDevice(did, device);
                providerService.deviceConnected(did, desc);
                log.info("Added device to ONOS core. Device Info: "
                                 + device.deviceInfo() + " " + did.uri().toString());
                //FIXME this description will be populated only if driver is pushed from outside
                // becuase otherwise default driver is used
                Device d = deviceService.getDevice(did);
                if (d.is(DeviceDescriptionDiscovery.class)) {
                    DeviceDescriptionDiscovery descriptionDiscovery = d.as(DeviceDescriptionDiscovery.class);
                    DeviceDescription description = descriptionDiscovery.discoverDeviceDetails();
                    if (description != null) {
                        deviceStore.createOrUpdateDevice(
                                new ProviderId("snmp", "org.onosproject.provider.device"),
                                did, description);
                    } else {
                        log.info("No other description given for device {}", d.id());
                    }
                    providerService.updatePorts(did, descriptionDiscovery.discoverPortDetails());
                } else {
                    log.warn("No populate description and ports behaviour for device {}", did);
                }
            } catch (Exception e) {
                log.error("Error while initializing session for the device: "
                                  + (device != null ? device.deviceInfo() : null), e);
            }
        }
    }

    private class InternalNetworkConfigListener implements NetworkConfigListener {


        @Override
        public void event(NetworkConfigEvent event) {
            if (event.configClass().equals(SnmpDeviceConfig.class)) {
                connectDevices();
            } else {
                log.warn("Injecting device via this Json is deprecated, " +
                                 "please put configuration under devices/");
                addOrRemoveDevicesConfig();
            }
        }

        @Override
        public boolean isRelevant(NetworkConfigEvent event) {
            return (event.configClass().equals(SnmpDeviceConfig.class) ||
                    event.configClass().equals(SnmpProviderConfig.class)) &&
                    (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
                            event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED);
        }
    }

    @Override
    public void changePortState(DeviceId deviceId, PortNumber portNumber,
                                boolean enable) {
        // TODO if required
    }
}
