/*
 * 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.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.TimerTask;
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 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.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 HashedWheelTimer timer = Timer.getTimer();
    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) {
        delay = 1000 / packetRate;
        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;

        public 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()) {
                sendEvent(devices.get(Math.min(currentDevice, devices.size() - 1)));
                currentDevice = (currentDevice + 1) % devices.size();
                timeout = timer.newTimeout(to.getTask(), delay, TimeUnit.MILLISECONDS);
            }
        }

        private void sendEvent(Device device) {
            // Make it look like things came from ports attached to hosts
            eth.setSourceMACAddress("00:00:10:00:00:0" + SRC_HOST)
                    .setDestinationMACAddress("00:00:10:00: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.
        }
    }

}
