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

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.
        }
    }

}
