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

import re
from typing import Callable, Dict, Iterator, List, Optional, Pattern, Union

from .jsonserializable import JsonSerializable
from .statistic import Scalar, Statistic
from .timeconversion import TimeConversion

class Group(JsonSerializable):
    """
    Used to create the heirarchical stats structure. A Group object contains a
    map of labeled  Groups, Statistics, Lists of Groups, or List of Statistics.
    """

    type: Optional[str]
    time_conversion: Optional[TimeConversion]

    def __init__(self, type: Optional[str] = None,
                 time_conversion: Optional[TimeConversion] = None,
                 **kwargs: Dict[str, Union["Group",Statistic,List["Group"],
                                           List["Statistic"]]]):
        if type is None:
            self.type = "Group"
        else:
            self.type = type

        self.time_conversion = time_conversion

        for key,value in kwargs.items():
            setattr(self, key, value)

    def children(self, predicate: Optional[Callable[[str], bool]] = None
                 ) -> Iterator[Union["Group", Statistic]]:
        """ Iterate through all of the children, optionally with a predicate

        ```
        >>> system.children(lambda _name: 'cpu' in name)
        [cpu0, cpu1, cpu2]
        ```

        :param: predicate(str) -> bool: Optional. Each child's name is passed
                to this function. If it returns true, then the child is
                yielded. Otherwise, the child is skipped.
                If not provided then all children are returned.
        """
        for attr in self.__dict__:
            # Check the provided predicate. If not a match, skip this child
            if predicate and not predicate(attr): continue
            obj = getattr(self, attr)
            if isinstance(obj, Group) or isinstance(obj, Statistic):
                yield obj

    def find(self, name: str) -> Iterator[Union["Group", Statistic]]:
        """ Find all stats that match the name

        This function searches all of the "children" in this group. It yields
        the set of attributes (children) that have the `name` as a substring.
        The order of the objects returned by the generator is arbitrary.

        ```
        >>> system.find('cpu')
        [cpu0, cpu1, cpu2, cpu3, other_cpu, ...]
        ```

        This is useful for performing aggregates over substats. For instance:

        ```
        >>> total_instructions = sum([cpu.exec_context.thread_0.numInsts.value
                                      for cpu in simstat.system.find('cpu')])
        100000
        ```

        :param: name: The name to search for
        """
        yield from self.children(lambda _name: _name in name)

    def find_re(self, regex: Union[str, Pattern]
                ) -> Iterator[Union["Group", Statistic]]:
        """ Find all stats that match the name

        This function searches all of the "children" in this group. It yields
        the set of attributes (children) that have the `name` mathing the
        regex provided. The order of the objects returned by the generator is
        arbitrary.

        ```
        >>> system.find_re('cpu[0-9]')
        [cpu0, cpu1, cpu2]
        ```
        Note: The above will not match `cpu_other`.

        :param: regex: The regular expression used to search. Can be a
                precompiled regex or a string in regex format
        """
        if isinstance(regex, str):
            regex = re.compile(regex)
        yield from self.children(lambda _name: regex.search(_name))

class Vector(Group):
    """
    The Vector class is used to store vector information. However, in gem5
    Vectors, in practise, hold information that is more like a dictionary of
    Scalar Values. This class may change, and may be merged into Group in
    accordance to decisions made in relation to
    https://gem5.atlassian.net/browse/GEM5-867.
    """
    def __init__(self, scalar_map: Dict[str,Scalar]):
        super(Vector, self).__init__(
                                     type="Vector",
                                     time_conversion=None,
                                     **scalar_map,
                                    )
