/*
 * Copyright (c) 2020-2021 ARM Limited
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "mem/ruby/network/simple/PerfectSwitch.hh"

#include <algorithm>

#include "base/cast.hh"
#include "base/cprintf.hh"
#include "base/random.hh"
#include "debug/RubyNetwork.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/network/simple/SimpleNetwork.hh"
#include "mem/ruby/network/simple/Switch.hh"
#include "mem/ruby/slicc_interface/Message.hh"

namespace gem5
{

namespace ruby
{

const int PRIORITY_SWITCH_LIMIT = 128;

PerfectSwitch::PerfectSwitch(SwitchID sid, Switch *sw, uint32_t virt_nets)
    : Consumer(sw, Switch::PERFECTSWITCH_EV_PRI),
      m_switch_id(sid), m_switch(sw)
{
    m_wakeups_wo_switch = 0;
    m_virtual_networks = virt_nets;
}

void
PerfectSwitch::init(SimpleNetwork *network_ptr)
{
    m_network_ptr = network_ptr;

    for (int i = 0;i < m_virtual_networks;++i) {
        m_pending_message_count.push_back(0);
    }
}

void
PerfectSwitch::addInPort(const std::vector<MessageBuffer*>& in)
{
    NodeID port = m_in.size();
    m_in.push_back(in);

    for (int i = 0; i < in.size(); ++i) {
        if (in[i] != nullptr) {
            in[i]->setConsumer(this);
            in[i]->setIncomingLink(port);
            in[i]->setVnet(i);
            updatePriorityGroups(i, in[i]);
        }
    }
}

void
PerfectSwitch::updatePriorityGroups(int vnet, MessageBuffer* in_buf)
{
    while (m_in_prio.size() <= vnet) {
        m_in_prio.emplace_back();
        m_in_prio_groups.emplace_back();
    }

    m_in_prio[vnet].push_back(in_buf);

    std::sort(m_in_prio[vnet].begin(), m_in_prio[vnet].end(),
        [](const MessageBuffer* i, const MessageBuffer* j)
        { return i->routingPriority() < j->routingPriority(); });

    // reset groups
    m_in_prio_groups[vnet].clear();
    int cur_prio = m_in_prio[vnet].front()->routingPriority();
    m_in_prio_groups[vnet].emplace_back();
    for (auto buf : m_in_prio[vnet]) {
        if (buf->routingPriority() != cur_prio)
            m_in_prio_groups[vnet].emplace_back();
        m_in_prio_groups[vnet].back().push_back(buf);
    }
}

void
PerfectSwitch::addOutPort(const std::vector<MessageBuffer*>& out,
                          const NetDest& routing_table_entry,
                          const PortDirection &dst_inport,
                          Tick routing_latency,
                          int link_weight)
{
    // Add to routing unit
    m_switch->getRoutingUnit().addOutPort(m_out.size(),
                                          out,
                                          routing_table_entry,
                                          dst_inport,
                                          link_weight);
    m_out.push_back({routing_latency, out});
}

PerfectSwitch::~PerfectSwitch()
{
}

MessageBuffer*
PerfectSwitch::inBuffer(int in_port, int vnet) const
{
    if (m_in[in_port].size() <= vnet) {
        return nullptr;
    }
    else {
        return m_in[in_port][vnet];
    }
}

void
PerfectSwitch::operateVnet(int vnet)
{
    if (m_pending_message_count[vnet] == 0)
        return;

    for (auto &in : m_in_prio_groups[vnet]) {
        // first check the port with the oldest message
        unsigned start_in_port = 0;
        Tick lowest_tick = MaxTick;
        for (int i = 0; i < in.size(); ++i) {
            MessageBuffer *buffer = in[i];
            if (buffer) {
                Tick ready_time = buffer->readyTime();
                if (ready_time < lowest_tick){
                    lowest_tick = ready_time;
                    start_in_port = i;
                }
            }
        }
        DPRINTF(RubyNetwork, "vnet %d: %d pending msgs. "
                            "Checking port %d first\n",
                vnet, m_pending_message_count[vnet], start_in_port);
        // check all ports starting with the one with the oldest message
        for (int i = 0; i < in.size(); ++i) {
            int in_port = (i + start_in_port) % in.size();
            MessageBuffer *buffer = in[in_port];
            if (buffer)
                operateMessageBuffer(buffer, vnet);
        }
    }
}

void
PerfectSwitch::operateMessageBuffer(MessageBuffer *buffer, int vnet)
{
    MsgPtr msg_ptr;
    Message *net_msg_ptr = NULL;

    // temporary vectors to store the routing results
    static thread_local std::vector<BaseRoutingUnit::RouteInfo> output_links;

    Tick current_time = m_switch->clockEdge();

    while (buffer->isReady(current_time)) {
        DPRINTF(RubyNetwork, "incoming: %d\n", buffer->getIncomingLink());

        // Peek at message
        msg_ptr = buffer->peekMsgPtr();
        net_msg_ptr = msg_ptr.get();
        DPRINTF(RubyNetwork, "Message: %s\n", (*net_msg_ptr));


        output_links.clear();
        m_switch->getRoutingUnit().route(*net_msg_ptr, vnet,
                                         m_network_ptr->isVNetOrdered(vnet),
                                         output_links);

        // Check for resources - for all outgoing queues
        bool enough = true;
        for (int i = 0; i < output_links.size(); i++) {
            int outgoing = output_links[i].m_link_id;
            OutputPort &out_port = m_out[outgoing];

            if (!out_port.buffers[vnet]->areNSlotsAvailable(1, current_time))
                enough = false;

            DPRINTF(RubyNetwork, "Checking if node is blocked ..."
                    "outgoing: %d, vnet: %d, enough: %d\n",
                    outgoing, vnet, enough);
        }

        // There were not enough resources
        if (!enough) {
            scheduleEvent(Cycles(1));
            DPRINTF(RubyNetwork, "Can't deliver message since a node "
                    "is blocked\n");
            DPRINTF(RubyNetwork, "Message: %s\n", (*net_msg_ptr));
            break; // go to next incoming port
        }

        MsgPtr unmodified_msg_ptr;

        if (output_links.size() > 1) {
            // If we are sending this message down more than one link
            // (size>1), we need to make a copy of the message so each
            // branch can have a different internal destination we need
            // to create an unmodified MsgPtr because the MessageBuffer
            // enqueue func will modify the message

            // This magic line creates a private copy of the message
            unmodified_msg_ptr = msg_ptr->clone();
        }

        // Dequeue msg
        buffer->dequeue(current_time);
        m_pending_message_count[vnet]--;

        // Enqueue it - for all outgoing queues
        for (int i=0; i<output_links.size(); i++) {
            int outgoing = output_links[i].m_link_id;
            OutputPort &out_port = m_out[outgoing];

            if (i > 0) {
                // create a private copy of the unmodified message
                msg_ptr = unmodified_msg_ptr->clone();
            }

            // Change the internal destination set of the message so it
            // knows which destinations this link is responsible for.
            net_msg_ptr = msg_ptr.get();
            net_msg_ptr->getDestination() = output_links[i].m_destinations;

            // Enqeue msg
            DPRINTF(RubyNetwork, "Enqueuing net msg from "
                    "inport[%d][%d] to outport [%d][%d].\n",
                    buffer->getIncomingLink(), vnet, outgoing, vnet);

            out_port.buffers[vnet]->enqueue(msg_ptr, current_time,
                                           out_port.latency);
        }
    }
}

void
PerfectSwitch::wakeup()
{
    // Give the highest numbered link priority most of the time
    m_wakeups_wo_switch++;
    int highest_prio_vnet = m_virtual_networks-1;
    int lowest_prio_vnet = 0;
    int decrementer = 1;

    // invert priorities to avoid starvation seen in the component network
    if (m_wakeups_wo_switch > PRIORITY_SWITCH_LIMIT) {
        m_wakeups_wo_switch = 0;
        highest_prio_vnet = 0;
        lowest_prio_vnet = m_virtual_networks-1;
        decrementer = -1;
    }

    // For all components incoming queues
    for (int vnet = highest_prio_vnet;
         (vnet * decrementer) >= (decrementer * lowest_prio_vnet);
         vnet -= decrementer) {
        operateVnet(vnet);
    }
}

void
PerfectSwitch::storeEventInfo(int info)
{
    m_pending_message_count[info]++;
}

void
PerfectSwitch::clearStats()
{
}
void
PerfectSwitch::collateStats()
{
}


void
PerfectSwitch::print(std::ostream& out) const
{
    out << "[PerfectSwitch " << m_switch_id << "]";
}

} // namespace ruby
} // namespace gem5
