package org.onlab.onos.net.host.impl;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.TimerTask;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.flow.instructions.Instruction;
import org.onlab.onos.net.flow.instructions.Instructions;
import org.onlab.onos.net.host.HostProvider;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.host.HostStore;
import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.packet.DefaultOutboundPacket;
import org.onlab.onos.net.packet.OutboundPacket;
import org.onlab.onos.net.packet.PacketService;
import org.onlab.onos.net.topology.TopologyService;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.util.Timer;

/**
 * Monitors hosts on the dataplane to detect changes in host data.
 * <p/>
 * The HostMonitor can monitor hosts that have already been detected for
 * changes. At an application's request, it can also monitor and actively
 * probe for hosts that have not yet been detected (specified by IP address).
 */
public class HostMonitor implements TimerTask {

    private static final byte[] DEFAULT_MAC_ADDRESS =
            MacAddress.valueOf("00:00:00:00:00:01").getAddress();

    private static final byte[] ZERO_MAC_ADDRESS =
            MacAddress.valueOf("00:00:00:00:00:00").getAddress();

    // TODO put on Ethernet
    private static final byte[] BROADCAST_MAC =
            MacAddress.valueOf("ff:ff:ff:ff:ff:ff").getAddress();

    private final HostService hostService;
    private final TopologyService topologyService;
    private final DeviceService deviceService;
    private final HostProvider hostProvider;
    private final PacketService packetService;
    private final HostStore hostStore;

    private final Set<IpAddress> monitoredAddresses;

    private final long probeRate;

    private Timeout timeout;

    public HostMonitor(HostService hostService, TopologyService topologyService,
                       DeviceService deviceService,
                       HostProvider hostProvider, PacketService packetService,
                       HostStore hostStore) {
        this.hostService = hostService;
        this.topologyService = topologyService;
        this.deviceService = deviceService;
        this.hostProvider = hostProvider;
        this.packetService = packetService;
        this.hostStore = hostStore;

        monitoredAddresses = new HashSet<>();

        probeRate = 30000; // milliseconds

        timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS);
    }

    public void addMonitoringFor(IpAddress ip) {
        monitoredAddresses.add(ip);
    }

    public void stopMonitoring(IpAddress ip) {
        monitoredAddresses.remove(ip);
    }

    public void shutdown() {
        timeout.cancel();
    }

    @Override
    public void run(Timeout timeout) throws Exception {
        for (IpAddress ip : monitoredAddresses) {
            Set<Host> hosts = Collections.emptySet(); //TODO hostService.getHostsByIp(ip);

            if (hosts.isEmpty()) {
                sendArpRequest(ip);
            } else {
                for (Host host : hosts) {
                    hostProvider.triggerProbe(host);
                }
            }
        }

        timeout = Timer.getTimer().newTimeout(this, probeRate, TimeUnit.MILLISECONDS);
    }

    /**
     * Sends an ARP request for the given IP address.
     *
     * @param targetIp IP address to ARP for
     */
    private void sendArpRequest(IpAddress targetIp) {

        // Find ports with an IP address in the target's subnet and sent ARP
        // probes out those ports.
        for (Device device : deviceService.getDevices()) {
            for (Port port : deviceService.getPorts(device.id())) {
                ConnectPoint cp = new ConnectPoint(device.id(), port.number());
                PortAddresses addresses = hostStore.getAddressBindingsForPort(cp);

                /*for (IpPrefix prefix : addresses.ips()) {
                    if (prefix.contains(targetIp)) {
                        sendProbe(device.id(), port, addresses, targetIp);
                    }
                }*/
            }
        }

        // TODO case where no address was found.
        // Broadcast out internal edge ports?
    }

    private void sendProbe(DeviceId deviceId, Port port, PortAddresses portAddresses,
            IpAddress targetIp) {
        Ethernet arpPacket = createArpFor(targetIp, portAddresses);

        List<Instruction> instructions = new ArrayList<>();
        instructions.add(Instructions.createOutput(port.number()));

        TrafficTreatment treatment =
                new DefaultTrafficTreatment.Builder()
                .add(Instructions.createOutput(port.number()))
                .build();

        OutboundPacket outboundPacket =
                new DefaultOutboundPacket(deviceId, treatment,
                        ByteBuffer.wrap(arpPacket.serialize()));

        packetService.emit(outboundPacket);
    }

    private Ethernet createArpFor(IpAddress targetIp, PortAddresses portAddresses) {

        ARP arp = new ARP();
        arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
           .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
           .setProtocolType(ARP.PROTO_TYPE_IP)
           .setProtocolAddressLength((byte) IpPrefix.INET_LEN);

        byte[] sourceMacAddress;
        if (portAddresses.mac() == null) {
            sourceMacAddress = DEFAULT_MAC_ADDRESS;
        } else {
            sourceMacAddress = portAddresses.mac().getAddress();
        }

        arp.setSenderHardwareAddress(sourceMacAddress)
           //TODO .setSenderProtocolAddress(portAddresses.ips().toOctets())
           .setTargetHardwareAddress(ZERO_MAC_ADDRESS)
           .setTargetProtocolAddress(targetIp.toOctets());

        Ethernet ethernet = new Ethernet();
        ethernet.setEtherType(Ethernet.TYPE_ARP)
                .setDestinationMACAddress(BROADCAST_MAC)
                .setSourceMACAddress(sourceMacAddress)
                .setPayload(arp);

        return ethernet;
    }
}
