/*
 * Copyright (c) 2020 Advanced Micro Devices, Inc.
 * Copyright (c) 2019,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/SimpleNetwork.hh"

#include <cassert>
#include <numeric>

#include "base/cast.hh"
#include "mem/ruby/common/NetDest.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/network/simple/SimpleLink.hh"
#include "mem/ruby/network/simple/Switch.hh"
#include "mem/ruby/network/simple/Throttle.hh"
#include "mem/ruby/profiler/Profiler.hh"

namespace gem5
{

namespace ruby
{

SimpleNetwork::SimpleNetwork(const Params &p)
    : Network(p), m_buffer_size(p.buffer_size),
      m_endpoint_bandwidth(p.endpoint_bandwidth),
      networkStats(this)
{
    // record the routers
    for (std::vector<BasicRouter*>::const_iterator i = p.routers.begin();
         i != p.routers.end(); ++i) {
        auto* s = safe_cast<Switch*>(*i);
        s->init_net_ptr(this);
        auto id = static_cast<size_t>(s->params().router_id);
        m_switches[id] = s;
    }

    const std::vector<int> &physical_vnets_channels =
        p.physical_vnets_channels;
    const std::vector<int> &physical_vnets_bandwidth =
        p.physical_vnets_bandwidth;
    bool physical_vnets = physical_vnets_channels.size() > 0;
    int vnets = p.number_of_virtual_networks;

    fatal_if(physical_vnets && (physical_vnets_channels.size() != vnets),
        "physical_vnets_channels must provide channel count for all vnets");

    fatal_if(!physical_vnets && (physical_vnets_bandwidth.size() != 0),
        "physical_vnets_bandwidth also requires physical_vnets_channels");

    fatal_if((physical_vnets_bandwidth.size() != vnets) &&
             (physical_vnets_bandwidth.size() != 0),
        "physical_vnets_bandwidth must provide BW for all vnets");
}

void
SimpleNetwork::init()
{
    Network::init();

    // The topology pointer should have already been initialized in
    // the parent class network constructor.
    assert(m_topology_ptr != NULL);
    m_topology_ptr->createLinks(this);
}

// From a switch to an endpoint node
void
SimpleNetwork::makeExtOutLink(SwitchID src, NodeID global_dest,
                              BasicLink* link,
                              std::vector<NetDest>& routing_table_entry)
{
    NodeID local_dest = getLocalNodeID(global_dest);
    assert(local_dest < m_nodes);
    assert(m_switches[src] != NULL);

    SimpleExtLink *simple_link = safe_cast<SimpleExtLink*>(link);

    // some destinations don't use all vnets, but Switch requires the size
    // output buffer list to match the number of vnets
    int num_vnets = params().number_of_virtual_networks;
    gem5_assert(num_vnets >= m_fromNetQueues[local_dest].size());
    m_fromNetQueues[local_dest].resize(num_vnets, nullptr);

    m_switches[src]->addOutPort(m_fromNetQueues[local_dest],
                                routing_table_entry[0],
                                simple_link->m_latency, 0,
                                simple_link->m_bw_multiplier, true);
}

// From an endpoint node to a switch
void
SimpleNetwork::makeExtInLink(NodeID global_src, SwitchID dest, BasicLink* link,
                          std::vector<NetDest>& routing_table_entry)
{
    NodeID local_src = getLocalNodeID(global_src);
    assert(local_src < m_nodes);
    m_switches[dest]->addInPort(m_toNetQueues[local_src]);
}

// From a switch to a switch
void
SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, BasicLink* link,
                                std::vector<NetDest>& routing_table_entry,
                                PortDirection src_outport,
                                PortDirection dst_inport)
{
    // Connect it to the two switches
    SimpleIntLink *simple_link = safe_cast<SimpleIntLink*>(link);

    m_switches[dest]->addInPort(simple_link->m_buffers);
    m_switches[src]->addOutPort(simple_link->m_buffers, routing_table_entry[0],
                                simple_link->m_latency,
                                simple_link->m_weight,
                                simple_link->m_bw_multiplier,
                                false,
                                dst_inport);
    // Maitain a global list of buffers (used for functional accesses only)
    m_int_link_buffers.insert(m_int_link_buffers.end(),
            simple_link->m_buffers.begin(), simple_link->m_buffers.end());
}

void
SimpleNetwork::regStats()
{
    Network::regStats();

    for (MessageSizeType type = MessageSizeType_FIRST;
         type < MessageSizeType_NUM; ++type) {
        networkStats.m_msg_counts[(unsigned int) type] =
            new statistics::Formula(&networkStats,
            csprintf("msg_count.%s", MessageSizeType_to_string(type)).c_str());
        networkStats.m_msg_counts[(unsigned int) type]
            ->flags(statistics::nozero)
            ;

        networkStats.m_msg_bytes[(unsigned int) type] =
            new statistics::Formula(&networkStats,
            csprintf("msg_byte.%s", MessageSizeType_to_string(type)).c_str());
        networkStats.m_msg_bytes[(unsigned int) type]
            ->flags(statistics::nozero)
            ;

        // Now state what the formula is.
        for (auto& it : m_switches) {
            *(networkStats.m_msg_counts[(unsigned int) type]) +=
                sum(it.second->getMsgCount(type));
        }

        *(networkStats.m_msg_bytes[(unsigned int) type]) =
            *(networkStats.m_msg_counts[(unsigned int) type]) *
                statistics::constant(Network::MessageSizeType_to_int(type));
    }
}

void
SimpleNetwork::collateStats()
{
    for (auto& it : m_switches) {
        it.second->collateStats();
    }
}

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

/*
 * The simple network has an array of switches. These switches have buffers
 * that need to be accessed for functional reads and writes. Also the links
 * between different switches have buffers that need to be accessed.
 */
bool
SimpleNetwork::functionalRead(Packet *pkt)
{
    for (auto& it : m_switches) {
        if (it.second->functionalRead(pkt))
            return true;
    }
    for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) {
        if (m_int_link_buffers[i]->functionalRead(pkt))
            return true;
    }

    return false;
}

bool
SimpleNetwork::functionalRead(Packet *pkt, WriteMask &mask)
{
    bool read = false;
    for (auto& it : m_switches) {
        if (it.second->functionalRead(pkt, mask))
            read = true;
    }
    for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) {
        if (m_int_link_buffers[i]->functionalRead(pkt, mask))
            read = true;
    }
    return read;
}

uint32_t
SimpleNetwork::functionalWrite(Packet *pkt)
{
    uint32_t num_functional_writes = 0;

    for (auto& it : m_switches) {
        num_functional_writes += it.second->functionalWrite(pkt);
    }

    for (unsigned int i = 0; i < m_int_link_buffers.size(); ++i) {
        num_functional_writes += m_int_link_buffers[i]->functionalWrite(pkt);
    }
    return num_functional_writes;
}

SimpleNetwork::
NetworkStats::NetworkStats(statistics::Group *parent)
    : statistics::Group(parent)
{

}

} // namespace ruby
} // namespace gem5
