# 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,
    Mapping,
    Optional,
    Pattern,
    Union,
)

from .serializable_stat import SerializableStat
from .statistic import Scalar, Statistic
from .timeconversion import TimeConversion

class Group(SerializableStat):
    """
    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):
            pattern = re.compile(regex)
        else:
            pattern = regex
        yield from self.children(lambda _name: bool(pattern.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: Mapping[str, Scalar]):
        super().__init__(type="Vector", time_conversion=None, **scalar_map)
