# Copyright (c) 2021 The Regents of the University of California
# 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 m5.ticks import fromSeconds
from m5.util.convert import toLatency, toMemoryBandwidth
from m5.objects import PyTrafficGen, Port

from .abstract_core import AbstractCore
from .abstract_generator_core import AbstractGeneratorCore

from ..utils.override import overrides

from enum import Enum


class TrafficModes(Enum):
    """The traffic mode class
    This class is an enum to store traffic mode in a more meaningful way
    """

    linear = 0
    random = 1


class ComplexTrafficParams:
    def __init__(
        self,
        mode: TrafficModes,
        duration: str,
        rate: str,
        block_size: int,
        min_addr: int,
        max_addr: int,
        rd_perc: int,
        data_limit: int,
    ):
        """The complex traffic params class
        This class is a container for parameters to create either a linear or
        random traffic. The complex generator core stores a list of complex
        traffic params for resolution after m5.instantiate is called.
        """
        self._mode = mode
        self._duration = duration
        self._rate = rate
        self._block_size = block_size
        self._min_addr = min_addr
        self._max_addr = max_addr
        self._rd_perc = rd_perc
        self._data_limit = data_limit


class ComplexGeneratorCore(AbstractGeneratorCore):
    def __init__(self):
        """The complex generator core interface.

        This class defines the interface for a generator core that will create
        a series of different types of traffic. This core uses PyTrafficGen to
        create and inject the synthetic traffic. This generator could be used
        to create more complex traffics that consist of linear and random
        traffic in different phases.
        """
        super(ComplexGeneratorCore, self).__init__()
        self.generator = PyTrafficGen()
        self._traffic_params = []
        self._traffic = []
        self._traffic_set = False

    @overrides(AbstractCore)
    def connect_dcache(self, port: Port) -> None:
        self.generator.port = port

    def add_linear(
        self,
        duration: str,
        rate: str,
        block_size: int,
        min_addr: int,
        max_addr: int,
        rd_perc: int,
        data_limit: int,
    ) -> None:
        """
        This function will add the params for a linear traffic to the list of
        traffic params in this generator core. These params will be later
        resolved by the start_traffic call. This core uses a PyTrafficGen to
        create the traffic based on the specified params below.

        :param duration: The number of ticks for the generator core to generate
        traffic.
        :param rate: The rate at which the synthetic data is read/written.
        :param block_size: The number of bytes to be read/written with each
        request.
        :param min_addr: The lower bound of the address range the generator
        will read/write from/to.
        :param max_addr: The upper bound of the address range the generator
        will read/write from/to.
        :param rd_perc: The percentage of read requests among all the generated
        requests. The write percentage would be equal to 100 - rd_perc.
        :param data_limit: The amount of data in bytes to read/write by the
        generator before stopping generation.
        """
        param = ComplexTrafficParams(
            TrafficModes.linear,
            duration,
            rate,
            block_size,
            min_addr,
            max_addr,
            rd_perc,
            data_limit,
        )
        self._traffic_params = self._traffic_params + [param]
        self._traffic_set = False

    def add_random(
        self,
        duration: str,
        rate: str,
        block_size: int,
        min_addr: int,
        max_addr: int,
        rd_perc: int,
        data_limit: int,
    ) -> None:
        """
        This function will add the params for a random traffic to the list of
        traffic params in this generator core. These params will be later
        resolved by the start_traffic call. This core uses a PyTrafficGen to
        create the traffic based on the specified params below.

        :param duration: The number of ticks for the generator core to generate
        traffic.
        :param rate: The rate at which the synthetic data is read/written.
        :param block_size: The number of bytes to be read/written with each
        request.
        :param min_addr: The lower bound of the address range the generator
        will read/write from/to.
        :param max_addr: The upper bound of the address range the generator
        will read/write from/to.
        :param rd_perc: The percentage of read requests among all the generated
        requests. The write percentage would be equal to 100 - rd_perc.
        :param data_limit: The amount of data in bytes to read/write by the
        generator before stopping generation.
        """
        param = ComplexTrafficParams(
            TrafficModes.random,
            duration,
            rate,
            block_size,
            min_addr,
            max_addr,
            rd_perc,
            data_limit,
        )
        self._traffic_params = self._traffic_params + [param]
        self._traffic_set = False

    def start_traffic(self) -> None:
        """
        This function first checks if there are any pending traffics that
        require creation, if so it will create the pending traffics based on
        traffic_params list and adds  them to the traffic list, then it starts
        generating the traffic at the top of the traffic list. It also pops the
        first element in the list so that every time this function is called a
        new traffic is generated, each instance of a call to this function
        should happen before each instance of the call to m5.simulate(). All
        the instances of calls to this function should happen after
        m5.instantiate()
        """
        if not self._traffic_set:
            self._set_traffic()
        if self._traffic:
            self.generator.start(self._traffic.pop(0))
        else:
            print("No phases left to generate!")

    def _set_traffic(self) -> None:
        """
        This function will pop params from traffic params list and create their
        respective traffic and adds the traffic to the core's traffic list.
        """
        while self._traffic_params:
            param = self._traffic_params.pop(0)
            mode = param._mode
            duration = param._duration
            rate = param._rate
            block_size = param._block_size
            min_addr = param._min_addr
            max_addr = param._max_addr
            rd_perc = param._rd_perc
            data_limit = param._data_limit

            if mode == TrafficModes.linear:
                traffic = self._create_linear_traffic(
                    duration,
                    rate,
                    block_size,
                    min_addr,
                    max_addr,
                    rd_perc,
                    data_limit,
                )
                self._traffic = self._traffic + [traffic]

            if mode == TrafficModes.random:
                traffic = self._create_random_traffic(
                    duration,
                    rate,
                    block_size,
                    min_addr,
                    max_addr,
                    rd_perc,
                    data_limit,
                )
                self._traffic = self._traffic + [traffic]

        self._traffic_set = True

    def _create_linear_traffic(
        self,
        duration: str,
        rate: str,
        block_size: int,
        min_addr: int,
        max_addr: int,
        rd_perc: int,
        data_limit: int,
    ) -> None:
        """
        This function yields (creates) a linear traffic based on the input
        params. Then it will yield (create) an exit traffic (exit traffic is
        used to exit the simulation).

        :param duration: The number of ticks for the generator core to generate
        traffic.
        :param rate: The rate at which the synthetic data is read/written.
        :param block_size: The number of bytes to be read/written with each
        request.
        :param min_addr: The lower bound of the address range the generator
        will read/write from/to.
        :param max_addr: The upper bound of the address range the generator
        will read/write from/to.
        :param rd_perc: The percentage of read requests among all the generated
        requests. The write percentage would be equal to 100 - rd_perc.
        :param data_limit: The amount of data in bytes to read/write by the
        generator before stopping generation.
        """
        duration = fromSeconds(toLatency(duration))
        rate = toMemoryBandwidth(rate)
        period = fromSeconds(block_size / rate)
        min_period = period
        max_period = period
        yield self.generator.createLinear(
            duration,
            min_addr,
            max_addr,
            block_size,
            min_period,
            max_period,
            rd_perc,
            data_limit,
        )
        yield self.generator.createExit(0)

    def _create_random_traffic(
        self,
        duration: str,
        rate: str,
        block_size: int,
        min_addr: int,
        max_addr: int,
        rd_perc: int,
        data_limit: int,
    ) -> None:
        """
        This function yields (creates) a random traffic based on the input
        params. Then it will yield (create) an exit traffic (exit traffic is
        used to exit the simulation).

        :param duration: The number of ticks for the generator core to generate
        traffic.
        :param rate: The rate at which the synthetic data is read/written.
        :param block_size: The number of bytes to be read/written with each
        request.
        :param min_addr: The lower bound of the address range the generator
        will read/write from/to.
        :param max_addr: The upper bound of the address range the generator
        will read/write from/to.
        :param rd_perc: The percentage of read requests among all the generated
        requests. The write percentage would be equal to 100 - rd_perc.
        :param data_limit: The amount of data in bytes to read/write by the
        generator before stopping generation.
        """
        duration = fromSeconds(toLatency(duration))
        rate = toMemoryBandwidth(rate)
        period = fromSeconds(block_size / rate)
        min_period = period
        max_period = period
        yield self.generator.createRandom(
            duration,
            min_addr,
            max_addr,
            block_size,
            min_period,
            max_period,
            rd_perc,
            data_limit,
        )
        yield self.generator.createExit(0)
