/*
 *  Copyright 2016-present 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.ui.impl.topo.util;

import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.statistic.Load;
import org.onosproject.ui.model.topo.UiLinkId;
import org.onosproject.ui.topo.BiLink;
import org.onosproject.ui.topo.LinkHighlight;
import org.onosproject.ui.topo.LinkHighlight.Flavor;
import org.onosproject.ui.topo.Mod;
import org.onosproject.ui.topo.TopoUtils.Magnitude;
import org.onosproject.ui.topo.TopoUtils.ValueLabel;

import java.util.HashSet;
import java.util.Set;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.ui.topo.LinkHighlight.Flavor.NO_HIGHLIGHT;
import static org.onosproject.ui.topo.LinkHighlight.Flavor.PRIMARY_HIGHLIGHT;
import static org.onosproject.ui.topo.LinkHighlight.Flavor.SECONDARY_HIGHLIGHT;
import static org.onosproject.ui.topo.TopoUtils.formatBytes;
import static org.onosproject.ui.topo.TopoUtils.formatClippedBitRate;
import static org.onosproject.ui.topo.TopoUtils.formatFlows;
import static org.onosproject.ui.topo.TopoUtils.formatPacketRate;

/**
 * Representation of a link and its inverse, and associated traffic data.
 * This class understands how to generate the appropriate
 * {@link LinkHighlight}s for showing traffic data on the topology view.
 */
public class TrafficLink extends BiLink {
    private static final Mod PORT_TRAFFIC_GREEN = new Mod("port-traffic-green");
    private static final Mod PORT_TRAFFIC_YELLOW = new Mod("port-traffic-yellow");
    private static final Mod PORT_TRAFFIC_ORANGE = new Mod("port-traffic-orange");
    private static final Mod PORT_TRAFFIC_RED = new Mod("port-traffic-red");

    private static final String EMPTY = "";

    private long bytes = 0;
    private long rate = 0;
    private long flows = 0;
    private Flavor taggedFlavor = NO_HIGHLIGHT;
    private boolean hasTraffic = false;
    private boolean isOptical = false;
    private boolean antMarch = false;
    private Set<Mod> mods = new HashSet<>();

    /**
     * Constructs a traffic link for the given key and initial link.
     *
     * @param key  canonical key for this traffic link
     * @param link first link
     */
    public TrafficLink(LinkKey key, Link link) {
        super(key, link);
    }


    /**
     * Returns an "empty" traffic link (one with no underlying links or stats)
     * with the given identifier. This is useful when we want to aggregate
     * stats from other links into a single entity (such as a region-region
     * link reporting the stats for the links that compose it).
     *
     * @param id the link identifier
     */
    public TrafficLink(UiLinkId id) {
        super(id);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        TrafficLink that = (TrafficLink) o;

        return bytes == that.bytes && rate == that.rate &&
                flows == that.flows && hasTraffic == that.hasTraffic &&
                isOptical == that.isOptical && antMarch == that.antMarch &&
                taggedFlavor == that.taggedFlavor && mods.equals(that.mods);
    }

    @Override
    public int hashCode() {
        int result = (int) (bytes ^ (bytes >>> 32));
        result = 31 * result + (int) (rate ^ (rate >>> 32));
        result = 31 * result + (int) (flows ^ (flows >>> 32));
        result = 31 * result + taggedFlavor.hashCode();
        result = 31 * result + (hasTraffic ? 1 : 0);
        result = 31 * result + (isOptical ? 1 : 0);
        result = 31 * result + (antMarch ? 1 : 0);
        result = 31 * result + mods.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("linkId", linkId())
                .add("bytes", bytes)
                .add("rate", rate)
                .add("flows", flows)
                .toString();
    }

    /**
     * Returns the count of bytes.
     *
     * @return the byte count
     */
    public long bytes() {
        return bytes;
    }

    /**
     * Returns the rate.
     *
     * @return the rate
     */
    public long rate() {
        return rate;
    }

    /**
     * Returns the flows.
     *
     * @return flow count
     */
    public long flows() {
        return flows;
    }

    /**
     * Sets the optical flag to the given value.
     *
     * @param b true if an optical link
     * @return self, for chaining
     */
    public TrafficLink optical(boolean b) {
        isOptical = b;
        return this;
    }

    /**
     * Sets the ant march flag to the given value.
     *
     * @param b true if marching ants required
     * @return self, for chaining
     */
    public TrafficLink antMarch(boolean b) {
        antMarch = b;
        return this;
    }

    /**
     * Tags this traffic link with the flavor to be used in visual rendering.
     *
     * @param flavor the flavor to tag
     * @return self, for chaining
     */
    public TrafficLink tagFlavor(Flavor flavor) {
        taggedFlavor = flavor;
        return this;
    }

    /**
     * Tags this traffic link with the mods to be used in visual rendering.
     *
     * @param mods the mods to tag on this link
     * @return self, for chaining
     */
    public TrafficLink tagMods(Set<Mod> mods) {
        if (mods != null) {
            this.mods.addAll(mods);
        }
        return this;
    }

    /**
     * Adds load statistics, marks the traffic link as having traffic.
     *
     * @param load load to add
     */
    public void addLoad(Load load) {
        addLoad(load, 0);
    }

    /**
     * Adds load statistics, marks the traffic link as having traffic, if the
     * load {@link Load#rate rate} is greater than the given threshold
     * (expressed in bytes per second).
     *
     * @param load      load to add
     * @param threshold threshold to register traffic
     */
    public void addLoad(Load load, double threshold) {
        if (load != null) {
            this.hasTraffic = hasTraffic || load.rate() > threshold;
            this.bytes += load.latest();
            this.rate += load.rate();
        }
    }

    /**
     * Adds the given count of flows to this traffic link.
     *
     * @param count count of flows
     */
    public void addFlows(int count) {
        this.flows += count;
    }

    /**
     * Merges the load recorded on the given traffic link into this one.
     *
     * @param other the other traffic link
     */
    public void mergeStats(TrafficLink other) {
        this.bytes += other.bytes;
        this.rate += other.rate;
        this.flows += other.flows;
    }


    @Override
    public LinkHighlight highlight(Enum<?> type) {
        StatsType statsType = (StatsType) type;
        switch (statsType) {
            case FLOW_COUNT:
                return highlightForFlowCount();

            case FLOW_STATS:
            case PORT_STATS:
            case PORT_PACKET_STATS:
                return highlightForStats(statsType);

            case TAGGED:
                return highlightForTagging();

            default:
                throw new IllegalStateException("unexpected case: " + statsType);
        }
    }

    private LinkHighlight highlightForStats(StatsType type) {
        ValueLabel vl = null;
        Mod m = null;

        // based on the type of stats, need to determine the label and "color"...
        switch (type) {
            case FLOW_STATS:
                vl = formatBytes(bytes);
                // default to "secondary highlighting" of link
                break;

            case PORT_STATS:
                vl = formatClippedBitRate(rate);

                // set color based on bits per second...
                if (vl.magnitude() == Magnitude.ONE ||
                        vl.magnitude() == Magnitude.KILO) {
                    m = PORT_TRAFFIC_GREEN;

                } else if (vl.magnitude() == Magnitude.MEGA) {
                    m = PORT_TRAFFIC_YELLOW;

                } else if (vl.magnitude() == Magnitude.GIGA) {
                    m = vl.clipped() ? PORT_TRAFFIC_RED : PORT_TRAFFIC_ORANGE;
                }
                break;

            case PORT_PACKET_STATS:
                vl = formatPacketRate(rate);

                // FIXME: Provisional color threshold parameters for packets
                // set color based on bits per second...
                if (rate < 10) {
                    m = PORT_TRAFFIC_GREEN;

                } else if (rate < 1000) {
                    m = PORT_TRAFFIC_YELLOW;

                } else if (rate < 100000) {
                    m = PORT_TRAFFIC_ORANGE;
                } else {
                    m = PORT_TRAFFIC_RED;
                }
                break;

            default:
                break;
        }

        LinkHighlight hlite = new LinkHighlight(linkId(), SECONDARY_HIGHLIGHT);
        if (vl != null) {
            hlite.setLabel(vl.toString());
        }
        if (m != null) {
            hlite.addMod(m);
        }

        return addCustomMods(hlite);
    }

    private LinkHighlight highlightForFlowCount() {
        Flavor flavor = flows > 0 ? PRIMARY_HIGHLIGHT : SECONDARY_HIGHLIGHT;
        LinkHighlight hlite = new LinkHighlight(linkId(), flavor)
                .setLabel(formatFlows(flows));

        return addCustomMods(hlite);
    }

    private LinkHighlight highlightForTagging() {
        LinkHighlight hlite = new LinkHighlight(linkId(), taggedFlavor)
                .setLabel(hasTraffic ? formatBytes(bytes).toString() : EMPTY);

        if (isOptical) {
            hlite.addMod(LinkHighlight.MOD_OPTICAL);
        }
        if (antMarch) {
            hlite.addMod(LinkHighlight.MOD_ANIMATED);
        }
        return addCustomMods(hlite);
    }

    private LinkHighlight addCustomMods(LinkHighlight hlite) {
        if (!mods.isEmpty()) {
            mods.forEach(hlite::addMod);
        }
        return hlite;
    }

    /**
     * Returns true if this link has been deemed to have enough traffic
     * to register on the topology view in the web UI.
     *
     * @return true if this link has displayable traffic
     */
    public boolean hasTraffic() {
        return hasTraffic;
    }

    /**
     * Designates type of traffic statistics to report on a highlighted link.
     */
    public enum StatsType {
        /**
         * Number of flows.
         */
        FLOW_COUNT,

        /**
         * Number of bytes.
         */
        FLOW_STATS,

        /**
         * Number of bits per second.
         */
        PORT_STATS,

        /**
         * Number of packets per second.
         */
        PORT_PACKET_STATS,

        /**
         * Custom tagged information.
         */
        TAGGED
    }
}
