# Copyright (c) 2012 Advanced Micro Devices, Inc.
# 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.

from topologies.BaseTopology import BaseTopology


class Cluster(BaseTopology):
    """A cluster is a group of nodes which are all one hop from eachother
    Clusters can also contain other clusters
    When creating this kind of topology, return a single cluster (usually
    the root cluster) from create_system in configs/ruby/<protocol>.py
    """

    _num_int_links = 0
    _num_ext_links = 0
    _num_routers = 0

    # Below methods for auto counting
    @classmethod
    def num_int_links(cls):
        cls._num_int_links += 1
        return cls._num_int_links - 1

    @classmethod
    def num_ext_links(cls):
        cls._num_ext_links += 1
        return cls._num_ext_links - 1

    @classmethod
    def num_routers(cls):
        cls._num_routers += 1
        return cls._num_routers - 1

    def __init__(self, intBW=0, extBW=0, intLatency=0, extLatency=0):
        """internalBandwidth is bandwidth of all links within the cluster
        externalBandwidth is bandwidth from this cluster to any cluster
            connecting to it.
        internal/externalLatency are similar
        **** When creating a cluster with sub-clusters, the sub-cluster
             external bandwidth overrides the internal bandwidth of the
             super cluster
        """
        self.nodes = []
        self.router = None  # created in makeTopology
        self.intBW = intBW
        self.extBW = extBW
        self.intLatency = intLatency
        self.extLatency = extLatency

    def add(self, node):
        self.nodes.append(node)

    def makeTopology(self, options, network, IntLink, ExtLink, Router):
        """Recursively make all of the links and routers"""

        # make a router to connect all of the nodes
        self.router = Router(router_id=self.num_routers())
        network.routers.append(self.router)

        for node in self.nodes:
            if type(node) == Cluster:
                node.makeTopology(options, network, IntLink, ExtLink, Router)

                # connect this cluster to the router
                link_out = IntLink(
                    link_id=self.num_int_links(),
                    src_node=self.router,
                    dst_node=node.router,
                )
                link_in = IntLink(
                    link_id=self.num_int_links(),
                    src_node=node.router,
                    dst_node=self.router,
                )

                if node.extBW:
                    link_out.bandwidth_factor = node.extBW
                    link_in.bandwidth_factor = node.extBW

                # if there is an internal b/w for this node
                # and no ext b/w to override
                elif self.intBW:
                    link_out.bandwidth_factor = self.intBW
                    link_in.bandwidth_factor = self.intBW

                if node.extLatency:
                    link_out.latency = node.extLatency
                    link_in.latency = node.extLatency
                elif self.intLatency:
                    link_out.latency = self.intLatency
                    link_in.latency = self.intLatency

                network.int_links.append(link_out)
                network.int_links.append(link_in)
            else:
                # node is just a controller,
                # connect it to the router via a ext_link
                link = ExtLink(
                    link_id=self.num_ext_links(),
                    ext_node=node,
                    int_node=self.router,
                )

                if self.intBW:
                    link.bandwidth_factor = self.intBW
                if self.intLatency:
                    link.latency = self.intLatency

                network.ext_links.append(link)

    def __len__(self):
        return len([i for i in self.nodes if type(i) != Cluster]) + sum(
            [len(i) for i in self.nodes if type(i) == Cluster]
        )
