/*
 * Copyright 2015 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.nil.link.impl;

import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.delay;
import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.Dictionary;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.DefaultLinkDescription;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderRegistry;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Provider which advertises fake/nonexistent links to the core. To be used for
 * benchmarking only.
 */
@Component(immediate = true)
public class NullLinkProvider extends AbstractProvider implements LinkProvider {

    private final Logger log = getLogger(getClass());

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

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

    private LinkProviderService providerService;

    private static final boolean FLICKER = false;
    private static final int DEFAULT_RATE = 3000;
    // For now, static switch port values
    private static final PortNumber SRCPORT = PortNumber.portNumber(5);
    private static final PortNumber DSTPORT = PortNumber.portNumber(6);

    private final InternalLinkProvider linkProvider = new InternalLinkProvider();

    // Link descriptions
    private final ConcurrentMap<ConnectPoint, LinkDescription> descriptions = Maps
            .newConcurrentMap();

    // Device ID's that have been seen so far
    private final List<DeviceId> devices = Lists.newArrayList();

    private ExecutorService linkDriver = Executors.newFixedThreadPool(1,
            namedThreads("null-link-driver"));

    // If true, 'flickers' links by alternating link up/down events at eventRate
    @Property(name = "flicker", boolValue = FLICKER,
            label = "Setting to flap links")
    private boolean flicker = FLICKER;

    // For flicker = true, duration between events in msec.
    @Property(name = "eventRate", intValue = DEFAULT_RATE,
            label = "Duration between Link Event")
    private int eventRate = 3000;

    public NullLinkProvider() {
        super(new ProviderId("null", "org.onosproject.provider.nil"));
    }

    @Activate
    public void activate(ComponentContext context) {
        providerService = providerRegistry.register(this);
        deviceService.addListener(linkProvider);
        modified(context);
        log.info("started");
    }

    @Deactivate
    public void deactivate(ComponentContext context) {
        if (flicker) {
            try {
                linkDriver.awaitTermination(1000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                log.error("LinkBuilder did not terminate");
            }
            linkDriver.shutdownNow();
        }
        deviceService.removeListener(linkProvider);
        providerRegistry.unregister(this);
        deviceService = null;

        log.info("stopped");
    }

    @Modified
    public void modified(ComponentContext context) {
        if (context == null) {
            log.info("No configs, using defaults: flicker={}, eventRate={}",
                    FLICKER, DEFAULT_RATE);
            return;
        }
        Dictionary<?, ?> properties = context.getProperties();

        boolean flickSetting;
        int newRate;
        try {
            String s = (String) properties.get("flicker");
            flickSetting = isNullOrEmpty(s) ? flicker : Boolean.valueOf(s);
            s = (String) properties.get("eventRate");
            newRate = isNullOrEmpty(s) ? eventRate : Integer.valueOf(s);
        } catch (Exception e) {
            log.warn(e.getMessage());
            flickSetting = flicker;
            newRate = eventRate;
        }

        if (flicker != flickSetting) {
            flicker = flickSetting;
        }

        if (flicker) {
            if (eventRate != newRate) {
                eventRate = newRate;
            }
            linkDriver.submit(new LinkDriver());
        }
        log.info("Using new settings: flicker={}, eventRate={}", flicker,
                eventRate);
    }

    /**
     * Adds links as devices are found, and generates LinkEvents.
     */
    private class InternalLinkProvider implements DeviceListener {

        @Override
        public void event(DeviceEvent event) {
            switch (event.type()) {
            case DEVICE_ADDED:
                addLink(event.subject());
                break;
            case DEVICE_REMOVED:
                removeLink(event.subject());
                break;
            default:
                break;
            }
        }

        private void addLink(Device current) {
            devices.add(current.id());
            // No link if only one device
            if (devices.size() == 1) {
                return;
            }

            // Attach new device to the last-seen device
            DeviceId prev = devices.get(devices.size() - 2);
            ConnectPoint src = new ConnectPoint(prev, SRCPORT);
            ConnectPoint dst = new ConnectPoint(current.id(), DSTPORT);

            LinkDescription fdesc = new DefaultLinkDescription(src, dst,
                    Link.Type.DIRECT);
            LinkDescription rdesc = new DefaultLinkDescription(dst, src,
                    Link.Type.DIRECT);
            descriptions.put(src, fdesc);
            descriptions.put(dst, rdesc);

            providerService.linkDetected(fdesc);
            providerService.linkDetected(rdesc);
        }

        private void removeLink(Device device) {
            providerService.linksVanished(device.id());
            devices.remove(device.id());
        }
    }

    /**
     * Generates link events using fake links.
     */
    private class LinkDriver implements Runnable {

        @Override
        public void run() {
            while (!linkDriver.isShutdown()) {
                for (LinkDescription desc : descriptions.values()) {
                    providerService.linkVanished(desc);
                    delay(eventRate);
                    providerService.linkDetected(desc);
                    delay(eventRate);
                }
            }
        }
    }
}
