package net.onrc.onos.core.intent;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;

import net.onrc.onos.core.topology.Link;
import net.onrc.onos.core.topology.LinkEvent;
import net.onrc.onos.core.topology.PortEvent.SwitchPort;

/**
 * In addition to maintaining the Intent ID to Intent mapping of its
 * superclass, this class maintains a mapping from switch port to
 * PathIntent. It is used to quickly identify Intents that are affected
 * when a network event involves a particular switch port.
 */
public class PathIntentMap extends IntentMap {
    private final HashMap<Long, HashMap<Long, HashSet<PathIntent>>> intents;

    /**
     * Constructor.
     */
    public PathIntentMap() {
        intents = new HashMap<>();
    }

    /**
     * Retrieve all PathIntents that contain the specified switch port.
     *
     * @param swPort the switch port to retrieve Intents for.
     * @return a set of all intents that contain swPort
     */
    private HashSet<PathIntent> get(SwitchPort swPort) {
        Long dpid = swPort.getDpid().value();
        Long port = (long) swPort.getNumber().value();
        HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
        if (portToIntents == null) {
            portToIntents = new HashMap<>();
            intents.put(dpid, portToIntents);
        }
        HashSet<PathIntent> targetIntents = portToIntents.get(port);
        if (targetIntents == null) {
            targetIntents = new HashSet<>();
            portToIntents.put(port, targetIntents);
        }
        return targetIntents;
    }

    /**
     * Add a PathIntent to a particular switch port.
     *
     * @param swPort switch port
     * @param intent Path Intent
     */
    private void put(SwitchPort swPort, PathIntent intent) {
        get(swPort).add(intent);
    }

    /**
     * Add a PathIntent to the map. The function will automatically
     * update the map with all switch ports contained in the Intent.
     *
     * @param intent the PathIntent
     */
    @Override
    protected void putIntent(Intent intent) {
        if (!(intent instanceof PathIntent)) {
            return; // TODO throw exception
        }
        super.putIntent(intent);

        PathIntent pathIntent = (PathIntent) intent;
        for (LinkEvent linkEvent : pathIntent.getPath()) {
            put(linkEvent.getSrc(), (PathIntent) intent);
            put(linkEvent.getDst(), (PathIntent) intent);
        }
    }

    /**
     * Removes a PathIntent from the map, including all switch ports.
     *
     * @param intentId the ID of the PathIntent to be removed
     */
    @Override
    protected void removeIntent(String intentId) {
        PathIntent intent = (PathIntent) getIntent(intentId);
        for (LinkEvent linkEvent : intent.getPath()) {
            get(linkEvent.getSrc()).remove(intent);
            get(linkEvent.getDst()).remove(intent);
        }
        super.removeIntent(intentId);
    }

    /**
     * Retrieve all intents that use a particular link.
     *
     * @param linkEvent the link to look up
     * @return a collection of PathIntents that use the link
     */
    public Collection<PathIntent> getIntentsByLink(LinkEvent linkEvent) {
        return getIntentsByPort(
                linkEvent.getSrc().getDpid().value(),
                (long) linkEvent.getSrc().getNumber().value());
    }

    /**
     * Retrieve all intents that use a particular port.
     *
     * @param dpid the switch's DPID
     * @param port the switch's port
     * @return a collection of PathIntents that use the port
     */
    public Collection<PathIntent> getIntentsByPort(Long dpid, Long port) {
        HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
        if (portToIntents != null) {
            HashSet<PathIntent> targetIntents = portToIntents.get(port);
            if (targetIntents != null) {
                return Collections.unmodifiableCollection(targetIntents);
            }
        }
        return new HashSet<>();
    }

    /**
     * Retrieve all intents that use a particular switch.
     *
     * @param dpid the switch's DPID
     * @return a collection of PathIntents that use the switch
     */
    public Collection<PathIntent> getIntentsByDpid(Long dpid) {
        HashSet<PathIntent> result = new HashSet<>();
        HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
        if (portToIntents != null) {
            for (HashSet<PathIntent> targetIntents : portToIntents.values()) {
                result.addAll(targetIntents);
            }
        }
        return result;
    }

    /**
     * Calculate available bandwidth of specified link.
     *
     * @param link the Link
     * @return the available bandwidth
     */
    public Double getAvailableBandwidth(Link link) {
        if (link == null) {
            return null;
        }
        Double bandwidth = link.getCapacity();
        LinkEvent linkEvent = new LinkEvent(link);
        if (!bandwidth.isInfinite()) {
            for (PathIntent intent : getIntentsByLink(linkEvent)) {
                Double intentBandwidth = intent.getBandwidth();
                if (intentBandwidth == null || intentBandwidth.isInfinite() || intentBandwidth.isNaN()) {
                    continue;
                }
                bandwidth -= intentBandwidth;
            }
        }
        return bandwidth;
    }
}
