# 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.

"""
This serves as the bridge between the gem5 statistics exposed via PyBind11 and
the Python Stats model.
"""

from datetime import datetime
from typing import IO, List, Union

import _m5.stats
from m5.objects import *
from m5.ext.pystats.group import *
from m5.ext.pystats.simstat import *
from m5.ext.pystats.statistic import *
from m5.ext.pystats.storagetype import *

class JsonOutputVistor():
    """
    This is a helper vistor class used to include a JSON output via the stats
    API (`src/python/m5/stats/__init__.py`).
    """
    file: str
    json_args: Dict

    def __init__(self, file: str, **kwargs):
        """
        Parameters
        ----------

        file: str
            The output file location in which the JSON will be dumped.

        kwargs: Dict[str, Any]
            Additional parameters to be passed to the `json.dumps` method.
        """

        self.file = file
        self.json_args = kwargs

    def dump(self, roots: Union[List[SimObject], Root]) -> None:
        """
        Dumps the stats of a simulation root (or list of roots) to the output
        JSON file specified in the JsonOutput constructor.

        WARNING: This dump assumes the statistics have already been prepared
        for the target root.

        Parameters
        ----------

        roots: Union[List[Root], Root]]
            The Root, or List of roots, whose stats are are to be dumped JSON.
        """

        with open(self.file, 'w') as fp:
            simstat = get_simstat(root=roots, prepare_stats=False)
            simstat.dump(fp=fp, **self.json_args)

def get_stats_group(group: _m5.stats.Group) -> Group:
    """
    Translates a gem5 Group object into a Python stats Group object. A Python
    statistic Group object is a dictionary of labeled Statistic objects. Any
    gem5 object passed to this will have its `getStats()` and `getStatGroups`
    function called, and all the stats translated (inclusive of the stats
    further down the hierarchy).

    Parameters
    ----------
    group: _m5.stats.Group
        The gem5 _m5.stats.Group object to be translated to be a Python stats
        Group object. Typically this will be a gem5 SimObject.

    Returns
    -------
    Group
        The stats group object translated from the input gem5 object.
    """

    stats_dict = {}

    for stat in group.getStats():
        statistic = __get_statistic(stat)
        if statistic is not None:
            stats_dict[stat.name] = statistic

    for key in group.getStatGroups():
        stats_dict[key] = get_stats_group(group.getStatGroups()[key])

    return Group(**stats_dict)

def __get_statistic(statistic: _m5.stats.Info) -> Optional[Statistic]:
    """
    Translates a _m5.stats.Info object into a Statistic object, to process
    statistics at the Python level.

    Parameters
    ----------
    statistic: Info
        The Info object to be translated to a Statistic object.

    Returns
    -------
    Optional[Statistic]
        The Statistic object of the Info object. Returns None if Info object
        cannot be translated.
    """

    assert(isinstance(statistic, _m5.stats.Info))
    statistic.prepare()

    if isinstance(statistic, _m5.stats.ScalarInfo):
        return __get_scaler(statistic)
    elif isinstance(statistic, _m5.stats.DistInfo):
        return __get_distribution(statistic)
    elif isinstance(statistic, _m5.stats.FormulaInfo):
        # We don't do anything with Formula's right now.
        # We may never do so, see https://gem5.atlassian.net/browse/GEM5-868.
        pass
    elif isinstance(statistic, _m5.stats.VectorInfo):
        return __get_vector(statistic)

    return None

def __get_scaler(statistic: _m5.stats.ScalarInfo) -> Scalar:
    value = statistic.value
    unit = statistic.unit
    description = statistic.desc
    # ScalarInfo uses the C++ `double`.
    datatype = StorageType["f64"]

    return Scalar(
                  value=value,
                  unit=unit,
                  description=description,
                  datatype=datatype,
                 )

def __get_distribution(statistic: _m5.stats.DistInfo) -> Distribution:
    unit = statistic.unit
    description = statistic.desc
    value = statistic.values
    bin_size = statistic.bucket_size
    min = statistic.min_val
    max = statistic.max_val
    num_bins = len(value)
    sum_val = statistic.sum
    sum_squared = statistic.squares
    underflow = statistic.underflow
    overflow = statistic.overflow
    logs = statistic.logs
    # DistInfo uses the C++ `double`.
    datatype = StorageType["f64"]

    return Distribution(
                        value=value,
                        min=min,
                        max=max,
                        num_bins=num_bins,
                        bin_size=bin_size,
                        sum = sum_val,
                        sum_squared = sum_squared,
                        underflow = underflow,
                        overflow = overflow,
                        logs = logs,
                        unit=unit,
                        description=description,
                        datatype=datatype,
                        )

def __get_vector(statistic: _m5.stats.VectorInfo) -> Vector:
    to_add = dict()

    for index in range(statistic.size):
        # All the values in a Vector are Scalar values
        value = statistic.value[index]
        unit = statistic.unit
        description = statistic.subdescs[index]
        # ScalarInfo uses the C++ `double`.
        datatype = StorageType["f64"]

        # Sometimes elements within a vector are defined by their name. Other
        # times they have no name. When a name is not available, we name the
        # stat the index value.
        if str(statistic.subnames[index]):
            index_string = str(statistic.subnames[index])
        else:
            index_string = str(index)

        to_add[index_string] = Scalar(
                                      value=value,
                                      unit=unit,
                                      description=description,
                                      datatype=datatype,
                                      )

    return Vector(scalar_map=to_add)

def _prepare_stats(group: _m5.stats.Group):
    """
    Prepares the statistics for dumping.
    """

    group.preDumpStats()

    for stat in group.getStats():
        stat.prepare()

    for child in group.getStatGroups().values():
        _prepare_stats(child)


def get_simstat(root: Union[SimObject, List[SimObject]],
                prepare_stats: bool = True) -> SimStat:
    """
    This function will return the SimStat object for a simulation given a
    SimObject (typically a Root SimObject), or list of SimObjects. The returned
    SimStat object will contain all the stats for all the SimObjects contained
    within the "root", inclusive of the "root" SimObject/SimObjects.

    Parameters
    ----------
    root: Union[SimObject, List[SimObject]]
        A SimObject, or list of SimObjects, of the simulation for translation
        into a SimStat object. Typically this is the simulation's Root
        SimObject as this will obtain the entirety of a run's statistics in a
        single SimStat object.

    prepare_stats: bool
        Dictates whether the stats are to be prepared prior to creating the
        SimStat object. By default this is 'True'.

    Returns
    -------
    SimStat
        The SimStat Object of the current simulation.

    """
    stats_map = {}
    creation_time = datetime.now()
    time_converstion = None # TODO https://gem5.atlassian.net/browse/GEM5-846
    final_tick = Root.getInstance().resolveStat("finalTick").value
    sim_ticks = Root.getInstance().resolveStat("simTicks").value
    simulated_begin_time = int(final_tick - sim_ticks)
    simulated_end_time = int(final_tick)

    if prepare_stats:
        _m5.stats.processDumpQueue()

    for r in root:
        if isinstance(r, Root):
            # The Root is a special case, we jump directly into adding its
            # constituent Groups.
            if prepare_stats:
                _prepare_stats(r)
            for key in r.getStatGroups():
                stats_map[key] = get_stats_group(r.getStatGroups()[key])
        elif isinstance(r, SimObject):
            if prepare_stats:
                _prepare_stats(r)
            stats_map[r.get_name()] = get_stats_group(r)
        else:
            raise TypeError("Object (" + str(r) + ") passed is not a "
                            "SimObject. " + __name__ + " only processes "
                            "SimObjects, or a list of  SimObjects.")



    return SimStat(
                   creation_time=creation_time,
                   time_conversion=time_converstion,
                   simulated_begin_time=simulated_begin_time,
                   simulated_end_time=simulated_end_time,
                   **stats_map,
                  )
