/*
 * 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.nil;

import org.onlab.packet.Ethernet;
import org.onlab.packet.ICMP;
import org.onlab.util.Timer;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceAdminService;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketProvider;
import org.onosproject.net.packet.PacketProviderService;
import org.slf4j.Logger;

import io.netty.util.Timeout;
import io.netty.util.TimerTask;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.google.common.collect.ImmutableList.copyOf;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.onosproject.net.MastershipRole.MASTER;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider which generates simulated packets and acts as a sink for outbound
 * packets. To be used for benchmarking only.
 */
class NullPacketProvider extends NullProviders.AbstractNullProvider
        implements PacketProvider {

    private static final int INITIAL_DELAY = 5;
    private final Logger log = getLogger(getClass());

    // Arbitrary host src/dst
    private static final int SRC_HOST = 2;
    private static final int DST_HOST = 5;

    // Time between event firing, in milliseconds
    private int delay;

    // TODO: use host service to pick legitimate hosts connected to devices
    private HostService hostService;
    private PacketProviderService providerService;

    private List<Device> devices;
    private int currentDevice = 0;

    private Timeout timeout;

    /**
     * Starts the packet generation process.
     *
     * @param packetRate      packets per second
     * @param hostService     host service
     * @param deviceService   device service
     * @param providerService packet provider service
     */
    void start(int packetRate, HostService hostService,
               DeviceAdminService deviceService,
               PacketProviderService providerService) {
        this.hostService = hostService;
        this.providerService = providerService;

        this.devices = copyOf(deviceService.getDevices()).stream()
                .filter(d -> deviceService.getRole(d.id()) == MASTER)
                .collect(Collectors.toList());

        adjustRate(packetRate);
        timeout = Timer.newTimeout(new PacketDriverTask(), INITIAL_DELAY, SECONDS);
    }

    /**
     * Adjusts packet rate.
     *
     * @param packetRate new packet rate
     */
    void adjustRate(int packetRate) {
        boolean needsRestart = delay == 0 && packetRate > 0;
        delay = packetRate > 0 ? 1000 / packetRate : 0;
        if (needsRestart) {
            timeout = Timer.newTimeout(new PacketDriverTask(), 1, MILLISECONDS);
        }
        log.info("Settings: packetRate={}, delay={}", packetRate, delay);
    }

    /**
     * Stops the packet generation process.
     */
    void stop() {
        if (timeout != null) {
            timeout.cancel();
        }
    }

    @Override
    public void emit(OutboundPacket packet) {
        // We don't have a network to emit to. Keep a counter here, maybe?
    }

    /**
     * Generates packet events at a given rate.
     */
    private class PacketDriverTask implements TimerTask {

        // Filler echo request
        ICMP icmp;
        Ethernet eth;

        PacketDriverTask() {
            icmp = new ICMP();
            icmp.setIcmpType((byte) 8).setIcmpCode((byte) 0).setChecksum((short) 0);
            eth = new Ethernet();
            eth.setEtherType(Ethernet.TYPE_IPV4);
            eth.setPayload(icmp);
        }

        @Override
        public void run(Timeout to) {
            if (!devices.isEmpty() && !to.isCancelled() && delay > 0) {
                sendEvent(devices.get(Math.min(currentDevice, devices.size() - 1)));
                currentDevice = (currentDevice + 1) % devices.size();
                timeout = to.timer().newTimeout(to.task(), delay, TimeUnit.MILLISECONDS);
            }
        }

        private void sendEvent(Device device) {
            // Make it look like things came from ports attached to hosts
            eth.setSourceMACAddress("00:00:00:10:00:0" + SRC_HOST)
                    .setDestinationMACAddress("00:00:00:10:00:0" + DST_HOST);
            InboundPacket inPkt = new DefaultInboundPacket(
                    new ConnectPoint(device.id(), PortNumber.portNumber(SRC_HOST)),
                    eth, ByteBuffer.wrap(eth.serialize()));
            providerService.processPacket(new NullPacketContext(inPkt, null));
        }
    }

     // Minimal PacketContext to make core and applications happy.
    private final class NullPacketContext extends DefaultPacketContext {
        private NullPacketContext(InboundPacket inPkt, OutboundPacket outPkt) {
            super(System.currentTimeMillis(), inPkt, outPkt, false);
        }

        @Override
        public void send() {
            // We don't send anything out.
        }
    }

}
