/*
 *  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.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);
    }

    /**
     * Copy constructor.
     *
     * @param copy the instance to copy
     */
    public TrafficLink(TrafficLink copy) {
        super(copy.key(), copy.one());
        setOther(copy.two());
        bytes = copy.bytes;
        rate = copy.rate;
        flows = copy.flows;
        taggedFlavor = copy.taggedFlavor;
        hasTraffic = copy.hasTraffic;
        isOptical = copy.isOptical;
        antMarch = copy.antMarch;
        mods.addAll(copy.mods);
    }

    @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("key", key())
                .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
    }
}
