/*
 * 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 <algorithm>

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

using namespace std;

const int PRIORITY_SWITCH_LIMIT = 128;

// Operator for helper class
bool
operator<(const LinkOrder& l1, const LinkOrder& l2)
{
    return (l1.m_value < l2.m_value);
}

PerfectSwitch::PerfectSwitch(SwitchID sid, Switch *sw, uint32_t virt_nets)
    : Consumer(sw)
{
    m_switch_id = sid;
    m_round_robin_start = 0;
    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 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);

            string desc =
                csprintf("[Queue from port %s %s %s to PerfectSwitch]",
                         to_string(m_switch_id), to_string(port),
                         to_string(i));

            in[i]->setDescription(desc);
            in[i]->setIncomingLink(port);
            in[i]->setVnet(i);
        }
    }
}

void
PerfectSwitch::addOutPort(const vector<MessageBuffer*>& out,
                          const NetDest& routing_table_entry)
{
    // Setup link order
    LinkOrder l;
    l.m_value = 0;
    l.m_link = m_out.size();
    m_link_order.push_back(l);

    // Add to routing table
    m_out.push_back(out);
    m_routing_table.push_back(routing_table_entry);
}

PerfectSwitch::~PerfectSwitch()
{
}

void
PerfectSwitch::operateVnet(int vnet)
{
    MsgPtr msg_ptr;
    Message *net_msg_ptr = NULL;

    // This is for round-robin scheduling
    int incoming = m_round_robin_start;
    m_round_robin_start++;
    if (m_round_robin_start >= m_in.size()) {
        m_round_robin_start = 0;
    }

    if(m_pending_message_count[vnet] > 0) {
        // for all input ports, use round robin scheduling
        for (int counter = 0; counter < m_in.size(); counter++) {
            // Round robin scheduling
            incoming++;
            if (incoming >= m_in.size()) {
                incoming = 0;
            }

            // temporary vectors to store the routing results
            vector<LinkID> output_links;
            vector<NetDest> output_link_destinations;

            // Is there a message waiting?
            if (m_in[incoming].size() <= vnet) {
                continue;
            }

            MessageBuffer *buffer = m_in[incoming][vnet];
            if (buffer == nullptr) {
                continue;
            }

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

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

                output_links.clear();
                output_link_destinations.clear();
                NetDest msg_dsts = net_msg_ptr->getDestination();

                // Unfortunately, the token-protocol sends some
                // zero-destination messages, so this assert isn't valid
                // assert(msg_dsts.count() > 0);

                assert(m_link_order.size() == m_routing_table.size());
                assert(m_link_order.size() == m_out.size());

                if (m_network_ptr->getAdaptiveRouting()) {
                    if (m_network_ptr->isVNetOrdered(vnet)) {
                        // Don't adaptively route
                        for (int out = 0; out < m_out.size(); out++) {
                            m_link_order[out].m_link = out;
                            m_link_order[out].m_value = 0;
                        }
                    } else {
                        // Find how clogged each link is
                        for (int out = 0; out < m_out.size(); out++) {
                            int out_queue_length = 0;
                            for (int v = 0; v < m_virtual_networks; v++) {
                                out_queue_length += m_out[out][v]->getSize();
                            }
                            int value =
                                (out_queue_length << 8) |
                                random_mt.random(0, 0xff);
                            m_link_order[out].m_link = out;
                            m_link_order[out].m_value = value;
                        }

                        // Look at the most empty link first
                        sort(m_link_order.begin(), m_link_order.end());
                    }
                }

                for (int i = 0; i < m_routing_table.size(); i++) {
                    // pick the next link to look at
                    int link = m_link_order[i].m_link;
                    NetDest dst = m_routing_table[link];
                    DPRINTF(RubyNetwork, "dst: %s\n", dst);

                    if (!msg_dsts.intersectionIsNotEmpty(dst))
                        continue;

                    // Remember what link we're using
                    output_links.push_back(link);

                    // Need to remember which destinations need this message in
                    // another vector.  This Set is the intersection of the
                    // routing_table entry and the current destination set.  The
                    // intersection must not be empty, since we are inside "if"
                    output_link_destinations.push_back(msg_dsts.AND(dst));

                    // Next, we update the msg_destination not to include
                    // those nodes that were already handled by this link
                    msg_dsts.removeNetDest(dst);
                }

                assert(msg_dsts.count() == 0);

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

                    if (!m_out[outgoing][vnet]->areNSlotsAvailable(1))
                        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();
                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];

                    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_link_destinations[i];

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

                    m_out[outgoing][vnet]->enqueue(msg_ptr);
                }
            }
        }
    }
}

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 << "]";
}
