/*
 * Copyright 2015, 2016 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.pim.impl;

import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.PIM;
import org.onlab.packet.pim.PIMHello;
import org.onlab.packet.pim.PIMHelloOption;
import org.onlab.packet.pim.PIMJoinPrune;
import org.onlab.packet.pim.PIMJoinPruneGroup;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.PacketService;
import org.slf4j.Logger;

import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * PIM Interface represents an ONOS Interface with IP and MAC addresses for
 * a given ConnectPoint.
 */
public final class PIMInterface {

    private final Logger log = getLogger(getClass());

    private final PacketService packetService;

    private Interface onosInterface;
    private final TrafficTreatment outputTreatment;

    // Our hello opt holdtime
    private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;

    // Our hello opt prune delay
    private int pruneDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;

    // Neighbor priority
    private int priority   = PIMHelloOption.DEFAULT_PRIORITY;

    // Our current genid
    private final int generationId;

    // The IP address of the DR
    private IpAddress drIpaddress;

    // A map of all our PIM neighbors keyed on our neighbors IP address
    private Map<IpAddress, PIMNeighbor> pimNeighbors = new HashMap<>();

    /**
     * Create a PIMInterface from an ONOS Interface.
     *
     * @param intf the ONOS Interface.
     * @param holdTime hold time
     * @param priority priority
     * @param propagationDelay propagation delay
     * @param overrideInterval override interval
     * @param packetService reference to the packet service
     */
    private PIMInterface(Interface intf,
                        short holdTime,
                        int priority,
                        short propagationDelay,
                        short overrideInterval,
                        PacketService packetService) {

        onosInterface = intf;
        outputTreatment = createOutputTreatment();
        this.holdtime = holdTime;
        this.packetService = packetService;
        IpAddress ourIp = getIpAddress();
        MacAddress mac = intf.mac();

        generationId = new Random().nextInt();

        // Create a PIM Neighbor to represent ourselves for DR election.
        PIMNeighbor us = new PIMNeighbor(ourIp, mac, holdTime, 0, priority, generationId);

        pimNeighbors.put(ourIp, us);
        drIpaddress = ourIp;
    }

    private TrafficTreatment createOutputTreatment() {
        return DefaultTrafficTreatment.builder()
                .setOutput(onosInterface.connectPoint().port())
                .build();
    }

    /**
     * Return the ONOS Interface.
     *
     * @return ONOS Interface.
     */
    public Interface getInterface() {
        return onosInterface;

    }

    /**
     * Set the ONOS Interface, it will override a previous value.
     *
     * @param intf ONOS Interface
     * @return PIM interface instance
     */
    public PIMInterface setInterface(Interface intf) {
        onosInterface = intf;
        return this;
    }

    /**
     * Get the set of IP Addresses associated with this interface.
     *
     * @return a set of Ip Addresses on this interface
     */
    public Set<InterfaceIpAddress> getIpAddresses() {
        return onosInterface.ipAddresses();
    }

    /**
     * Return a single "best" IP address.
     *
     * @return the choosen IP address or null if none
     */
    public IpAddress getIpAddress() {
        if (onosInterface.ipAddresses().isEmpty()) {
            return null;
        }

        IpAddress ipaddr = null;
        for (InterfaceIpAddress ifipaddr : onosInterface.ipAddresses()) {
            ipaddr = ifipaddr.ipAddress();
            break;
        }
        return ipaddr;
    }

    /**
     * Get the holdtime.
     *
     * @return the holdtime
     */
    public short getHoldtime() {
        return holdtime;
    }

    /**
     * Get the prune delay.
     *
     * @return The prune delay
     */
    public int getPruneDelay() {
        return pruneDelay;
    }

    /**
     * Get our hello priority.
     *
     * @return our priority
     */
    public int getPriority() {
        return priority;
    }

    /**
     * Get our generation ID.
     *
     * @return our generation ID
     */
    public int getGenerationId() {
        return generationId;
    }

    /**
     * Gets the neighbors seen on this interface.
     *
     * @return PIM neighbors
     */
    public Collection<PIMNeighbor> getNeighbors() {
        return pimNeighbors.values();
    }

    /**
     * Checks whether any of our neighbors have expired, and cleans up their
     * state if they have.
     */
    public void checkNeighborTimeouts() {
        Set<PIMNeighbor> expired = pimNeighbors.values().stream()
                // Don't time ourselves out!
                .filter(neighbor -> !neighbor.ipAddress().equals(getIpAddress()))
                .filter(neighbor -> neighbor.isExpired())
                .collect(Collectors.toSet());

        for (PIMNeighbor neighbor : expired) {
            log.info("Timing out neighbor {}", neighbor);
            pimNeighbors.remove(neighbor.ipAddress(), neighbor);
        }
    }

    /**
     * Multicast a hello message out our interface.  This hello message is sent
     * periodically during the normal PIM Neighbor refresh time, as well as a
     * result of a newly created interface.
     */
    public void sendHello() {
        // Create the base PIM Packet and mark it a hello packet
        PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);

        // We need to set the source MAC and IPv4 addresses
        pimPacket.setSrcMacAddr(onosInterface.mac());
        pimPacket.setSrcIpAddress(Ip4Address.valueOf(getIpAddress().toOctets()));

        // Create the hello message with options
        PIMHello hello = new PIMHello();
        hello.createDefaultOptions();
        hello.addOption(PIMHelloOption.createHoldTime(holdtime));
        hello.addOption(PIMHelloOption.createPriority(priority));
        hello.addOption(PIMHelloOption.createGenID(generationId));

        // Now set the hello option payload
        pimPacket.setPIMPayload(hello);

        packetService.emit(new DefaultOutboundPacket(
                onosInterface.connectPoint().deviceId(),
                outputTreatment,
                ByteBuffer.wrap(pimPacket.getEthernet().serialize())));
    }

    /**
     * Process an incoming PIM Hello message.  There are a few things going on in
     * this method:
     * <ul>
     *     <li>We <em>may</em> have to create a new neighbor if one does not already exist</li>
     *     <li>We <em>may</em> need to re-elect a new DR if new information is received</li>
     *     <li>We <em>may</em> need to send an existing neighbor all joins if the genid changed</li>
     *     <li>We will refresh the neighbor's timestamp</li>
     * </ul>
     *
     * @param ethPkt the Ethernet packet header
     */
    public void processHello(Ethernet ethPkt) {

        // We'll need to save our neighbors MAC address
        MacAddress nbrmac = ethPkt.getSourceMAC();

        // And we'll need to save neighbors IP Address.
        IPv4 iphdr = (IPv4) ethPkt.getPayload();
        IpAddress srcip = IpAddress.valueOf(iphdr.getSourceAddress());

        PIM pimhdr = (PIM) iphdr.getPayload();
        if (pimhdr.getPimMsgType() != PIM.TYPE_HELLO) {
            log.error("process Hello has received a non hello packet type: " + pimhdr.getPimMsgType());
            return;
        }

        // get the DR values for later calculation
        PIMNeighbor dr = pimNeighbors.get(drIpaddress);
        checkNotNull(dr);

        IpAddress drip = drIpaddress;
        int drpri = dr.priority();

        // Assume we do not need to run a DR election
        boolean reElectDr = false;
        boolean genidChanged = false;

        PIMHello hello = (PIMHello) pimhdr.getPayload();

        // Determine if we already have a PIMNeighbor
        PIMNeighbor nbr = pimNeighbors.getOrDefault(srcip, null);
        PIMNeighbor newNbr = PIMNeighbor.createPimNeighbor(srcip, nbrmac, hello.getOptions().values());

        if (nbr == null) {
            pimNeighbors.putIfAbsent(srcip, newNbr);
            nbr = newNbr;
        } else if (!nbr.equals(newNbr)) {
            if (newNbr.holdtime() == 0) {
                // Neighbor has shut down. Remove them and clean up
                pimNeighbors.remove(srcip, nbr);
                return;
            } else {
                // Neighbor has changed one of their options.
                pimNeighbors.put(srcip, newNbr);
                nbr = newNbr;
            }
        }

        // Refresh this neighbor's timestamp
        nbr.refreshTimestamp();

        /*
         * the election method will first determine if an election
         * needs to be run, if so it will run the election.  The
         * IP address of the DR will be returned.  If the IP address
         * of the DR is different from what we already have we know a
         * new DR has been elected.
         */
        IpAddress electedIp = election(nbr, drip, drpri);
        if (!drip.equals(electedIp)) {
            // we have a new DR.
            drIpaddress = electedIp;
        }
    }

    // Run an election if we need to.  Return the elected IP address.
    private IpAddress election(PIMNeighbor nbr, IpAddress drIp, int drPriority) {

        IpAddress nbrIp = nbr.ipAddress();
        if (nbr.priority() > drPriority) {
            return nbrIp;
        }

        if (nbrIp.compareTo(drIp) > 0) {
            return nbrIp;
        }
        return drIp;
    }

    /**
     * Process an incoming PIM JoinPrune message.
     *
     * @param ethPkt the Ethernet packet header.
     */
    public void processJoinPrune(Ethernet ethPkt) {

        IPv4 ip = (IPv4) ethPkt.getPayload();
        checkNotNull(ip);

        PIM pim = (PIM) ip.getPayload();
        checkNotNull(pim);

        PIMJoinPrune jpHdr = (PIMJoinPrune) pim.getPayload();
        checkNotNull(jpHdr);

        /*
         * The Join/Prune messages are grouped by Group address. We'll walk each group address
         * where we will possibly have to walk a list of source address for the joins and prunes.
         */
        Collection<PIMJoinPruneGroup> jpgs = jpHdr.getJoinPrunes();
        for (PIMJoinPruneGroup jpg : jpgs) {
            IpPrefix gpfx = jpg.getGroup();

            // Walk the joins first.
            for (IpPrefix spfx : jpg.getJoins().values()) {

                // We may need


            }

            for (IpPrefix spfx : jpg.getPrunes().values()) {

                // TODO: this is where we many need to remove multi-cast state and possibly intents.

            }
        }

    }

    /**
     * Returns a builder for a PIM interface.
     *
     * @return PIM interface builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder for a PIM interface.
     */
    public static class Builder {
        private Interface intf;
        private PacketService packetService;
        private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
        private int priority   = PIMHelloOption.DEFAULT_PRIORITY;
        private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
        private short overrideInterval = PIMHelloOption.DEFAULT_OVERRIDEINTERVAL;

        /**
         * Uses the specified ONOS interface.
         *
         * @param intf ONOS interface
         * @return this PIM interface builder
         */
        public Builder withInterface(Interface intf) {
            this.intf = checkNotNull(intf);
            return this;
        }

        /**
         * Sets the reference to the packet service.
         *
         * @param packetService packet service
         * @return this PIM interface builder
         */
        public Builder withPacketService(PacketService packetService) {
            this.packetService = checkNotNull(packetService);
            return this;
        }

        /**
         * Uses the specified hold time.
         *
         * @param holdTime hold time in seconds
         * @return this PIM interface builder
         */
        public Builder withHoldTime(short holdTime) {
            this.holdtime = holdTime;
            return this;
        }

        /**
         * Uses the specified DR priority.
         *
         * @param priority DR priority
         * @return this PIM interface builder
         */
        public Builder withPriority(int priority) {
            this.priority = priority;
            return this;
        }

        /**
         * Uses the specified propagation delay.
         *
         * @param propagationDelay propagation delay in ms
         * @return this PIM interface builder
         */
        public Builder withPropagationDelay(short propagationDelay) {
            this.propagationDelay = propagationDelay;
            return this;
        }

        /**
         * Uses the specified override interval.
         *
         * @param overrideInterval override interval in ms
         * @return this PIM interface builder
         */
        public Builder withOverrideInterval(short overrideInterval) {
            this.overrideInterval = overrideInterval;
            return this;
        }

        /**
         * Builds the PIM interface.
         *
         * @return PIM interface
         */
        public PIMInterface build() {
            checkArgument(intf != null, "Must provide an interface");
            checkArgument(packetService != null, "Must provide a packet service");

            return new PIMInterface(intf, holdtime, priority, propagationDelay,
                    overrideInterval, packetService);
        }

    }
}
