# Copyright (c) 2017-2020 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) 2007 The Regents of The University of Michigan
# Copyright (c) 2010 The Hewlett-Packard Development Company
# 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.

import m5

import _m5.stats
from m5.objects import Root
from m5.params import isNullPointer
from .gem5stats import JsonOutputVistor
from m5.util import attrdict, fatal

# Stat exports
from _m5.stats import schedStatEvent as schedEvent
from _m5.stats import periodicStatDump

outputList = []

# Dictionary of stat visitor factories populated by the _url_factory
# visitor.
factories = {}

# List of all factories. Contains tuples of (factory, schemes,
# enabled).
all_factories = []


def _url_factory(schemes, enable=True):
    """Wrap a plain Python function with URL parsing helpers

    Wrap a plain Python function f(fn, **kwargs) to expect a URL that
    has been split using urlparse.urlsplit. First positional argument
    is assumed to be a filename, this is created as the concatenation
    of the netloc (~hostname) and path in the parsed URL. Keyword
    arguments are derived from the query values in the URL.

    Arguments:
        schemes: A list of URL schemes to use for this function.

    Keyword arguments:
        enable: Enable/disable this factory. Typically used when the
                presence of a function depends on some runtime property.

    For example:
        wrapped_f(urlparse.urlsplit("text://stats.txt?desc=False")) ->
        f("stats.txt", desc=False)

    """

    from functools import wraps

    def decorator(func):
        @wraps(func)
        def wrapper(url):
            try:
                from urllib.parse import parse_qs
            except ImportError:
                # Python 2 fallback
                from urlparse import parse_qs
            from ast import literal_eval

            qs = parse_qs(url.query, keep_blank_values=True)

            # parse_qs returns a list of values for each parameter. Only
            # use the last value since kwargs don't allow multiple values
            # per parameter. Use literal_eval to transform string param
            # values into proper Python types.
            def parse_value(key, values):
                if len(values) == 0 or (len(values) == 1 and not values[0]):
                    fatal(
                        "%s: '%s' doesn't have a value." % (url.geturl(), key)
                    )
                elif len(values) > 1:
                    fatal(
                        "%s: '%s' has multiple values." % (url.geturl(), key)
                    )
                else:
                    try:
                        return key, literal_eval(values[0])
                    except ValueError:
                        fatal(
                            "%s: %s isn't a valid Python literal"
                            % (url.geturl(), values[0])
                        )

            kwargs = dict([parse_value(k, v) for k, v in qs.items()])

            try:
                return func("%s%s" % (url.netloc, url.path), **kwargs)
            except TypeError:
                fatal("Illegal stat visitor parameter specified")

        all_factories.append((wrapper, schemes, enable))
        for scheme in schemes:
            assert scheme not in factories
            factories[scheme] = wrapper if enable else None
        return wrapper

    return decorator


@_url_factory([None, "", "text", "file"])
def _textFactory(fn, desc=True, spaces=True):
    """Output stats in text format.

    Text stat files contain one stat per line with an optional
    description. The description is enabled by default, but can be
    disabled by setting the desc parameter to False.

    Parameters:
      * desc (bool): Output stat descriptions (default: True)
      * spaces (bool): Output alignment spaces (default: True)

    Example:
      text://stats.txt?desc=False;spaces=False

    """

    return _m5.stats.initText(fn, desc, spaces)


@_url_factory(["h5"], enable=hasattr(_m5.stats, "initHDF5"))
def _hdf5Factory(fn, chunking=10, desc=True, formulas=True):
    """Output stats in HDF5 format.

    The HDF5 file format is a structured binary file format. It has
    the multiple benefits over traditional text stat files:

      * Efficient storage of time series (multiple stat dumps)
      * Fast lookup of stats
      * Plenty of existing tooling (e.g., Python libraries and graphical
        viewers)
      * File format can be used to store frame buffers together with
        normal stats.

    There are some drawbacks compared to the default text format:
      * Large startup cost (single stat dump larger than text equivalent)
      * Stat dumps are slower than text


    Known limitations:
      * Distributions and histograms currently unsupported.
      * No support for forking.


    Parameters:
      * chunking (unsigned): Number of time steps to pre-allocate (default: 10)
      * desc (bool): Output stat descriptions (default: True)
      * formulas (bool): Output derived stats (default: True)

    Example:
      h5://stats.h5?desc=False;chunking=100;formulas=False

    """

    return _m5.stats.initHDF5(fn, chunking, desc, formulas)


@_url_factory(["json"])
def _jsonFactory(fn):
    """Output stats in JSON format.

    Example:
      json://stats.json

    """

    return JsonOutputVistor(fn)


def addStatVisitor(url):
    """Add a stat visitor specified using a URL string

    Stat visitors are specified using URLs on the following format:
    format://path[?param=value[;param=value]]

    The available formats are listed in the factories list. Factories
    are called with the path as the first positional parameter and the
    parameters are keyword arguments. Parameter values must be valid
    Python literals.

    """

    try:
        from urllib.parse import urlsplit
    except ImportError:
        # Python 2 fallback
        from urlparse import urlsplit

    parsed = urlsplit(url)

    try:
        factory = factories[parsed.scheme]
    except KeyError:
        fatal("Illegal stat file type '%s' specified." % parsed.scheme)

    if factory is None:
        fatal("Stat type '%s' disabled at compile time" % parsed.scheme)

    outputList.append(factory(parsed))


def printStatVisitorTypes():
    """List available stat visitors and their documentation"""

    import inspect

    def print_doc(doc):
        for line in doc.splitlines():
            print("| %s" % line)
        print()

    enabled_visitors = [x for x in all_factories if x[2]]
    for factory, schemes, _ in enabled_visitors:
        print("%s:" % ", ".join(filter(lambda x: x is not None, schemes)))

        # Try to extract the factory doc string
        print_doc(inspect.getdoc(factory))


def initSimStats():
    _m5.stats.initSimStats()
    _m5.stats.registerPythonStatsHandlers()


def _visit_groups(visitor, root=None):
    if root is None:
        root = Root.getInstance()
    for group in root.getStatGroups().values():
        visitor(group)
        _visit_groups(visitor, root=group)


def _visit_stats(visitor, root=None):
    def for_each_stat(g):
        for stat in g.getStats():
            visitor(g, stat)

    _visit_groups(for_each_stat, root=root)


def _bindStatHierarchy(root):
    def _bind_obj(name, obj):
        if isNullPointer(obj):
            return
        if m5.SimObject.isSimObjectVector(obj):
            if len(obj) == 1:
                _bind_obj(name, obj[0])
            else:
                for idx, obj in enumerate(obj):
                    _bind_obj("{}{}".format(name, idx), obj)
        else:
            # We need this check because not all obj.getCCObject() is an
            # instance of Stat::Group. For example, sc_core::sc_module, the C++
            # class of SystemC_ScModule, is not a subclass of Stat::Group. So
            # it will cause a type error if obj is a SystemC_ScModule when
            # calling addStatGroup().
            if isinstance(obj.getCCObject(), _m5.stats.Group):
                parent = root
                while parent:
                    if hasattr(parent, "addStatGroup"):
                        parent.addStatGroup(name, obj.getCCObject())
                        break
                    parent = parent.get_parent()

            _bindStatHierarchy(obj)

    for name, obj in root._children.items():
        _bind_obj(name, obj)


names = []
stats_dict = {}
stats_list = []


def enable():
    """Enable the statistics package.  Before the statistics package is
    enabled, all statistics must be created and initialized and once
    the package is enabled, no more statistics can be created."""

    def check_stat(group, stat):
        if not stat.check() or not stat.baseCheck():
            fatal(
                "statistic '%s' (%d) was not properly initialized "
                "by a regStats() function\n",
                stat.name,
                stat.id,
            )

        if not (stat.flags & flags.display):
            stat.name = "__Stat%06d" % stat.id

    # Legacy stat
    global stats_list
    stats_list = list(_m5.stats.statsList())

    for stat in stats_list:
        check_stat(None, stat)

    stats_list.sort(key=lambda s: s.name.split("."))
    for stat in stats_list:
        stats_dict[stat.name] = stat
        stat.enable()

    # New stats
    _visit_stats(check_stat)
    _visit_stats(lambda g, s: s.enable())

    _m5.stats.enable()


def prepare():
    """Prepare all stats for data access.  This must be done before
    dumping and serialization."""

    # Legacy stats
    for stat in stats_list:
        stat.prepare()

    # New stats
    _visit_stats(lambda g, s: s.prepare())


def _dump_to_visitor(visitor, roots=None):
    # New stats
    def dump_group(group):
        for stat in group.getStats():
            stat.visit(visitor)
        for n, g in group.getStatGroups().items():
            visitor.beginGroup(n)
            dump_group(g)
            visitor.endGroup()

    if roots:
        # New stats from selected subroots.
        for root in roots:
            for p in root.path_list():
                visitor.beginGroup(p)
            dump_group(root)
            for p in reversed(root.path_list()):
                visitor.endGroup()
    else:
        # New stats starting from root.
        dump_group(Root.getInstance())

        # Legacy stats
        for stat in stats_list:
            stat.visit(visitor)


lastDump = 0
# List[SimObject].
global_dump_roots = []


def dump(roots=None):
    """Dump all statistics data to the registered outputs"""

    all_roots = []
    if roots is not None:
        all_roots.extend(roots)
    global global_dump_roots
    all_roots.extend(global_dump_roots)

    now = m5.curTick()
    global lastDump
    assert lastDump <= now
    new_dump = lastDump != now
    lastDump = now

    # Don't allow multiple global stat dumps in the same tick. It's
    # still possible to dump a multiple sub-trees.
    if not new_dump and not all_roots:
        return

    # Only prepare stats the first time we dump them in the same tick.
    if new_dump:
        _m5.stats.processDumpQueue()
        # Notify new-style stats group that we are about to dump stats.
        sim_root = Root.getInstance()
        if sim_root:
            sim_root.preDumpStats()
        prepare()

    for output in outputList:
        if isinstance(output, JsonOutputVistor):
            if not all_roots:
                output.dump(Root.getInstance())
            else:
                output.dump(all_roots)
        else:
            if output.valid():
                output.begin()
                _dump_to_visitor(output, roots=all_roots)
                output.end()


def reset():
    """Reset all statistics to the base state"""

    # call reset stats on all SimObjects
    root = Root.getInstance()
    if root:
        root.resetStats()

    # call any other registered legacy stats reset callbacks
    for stat in stats_list:
        stat.reset()

    _m5.stats.processResetQueue()


flags = attrdict(
    {
        "none": 0x0000,
        "init": 0x0001,
        "display": 0x0002,
        "total": 0x0010,
        "pdf": 0x0020,
        "cdf": 0x0040,
        "dist": 0x0080,
        "nozero": 0x0100,
        "nonan": 0x0200,
    }
)
