/*
 * 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.max(currentDevice, devices.size())));
                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.
        }
    }

}
