# 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 abc import ABC
from typing import Any, Iterable, Optional, Union, List

from .jsonserializable import JsonSerializable
from .storagetype import StorageType

class Statistic(ABC, JsonSerializable):
    """
    The abstract base class for all Python statistics.
    """

    value: Any
    type: Optional[str]
    unit: Optional[str]
    description: Optional[str]
    datatype: Optional[StorageType]

    def __init__(self, value: Any, type: Optional[str] = None,
                 unit: Optional[str] = None,
                 description: Optional[str] = None,
                 datatype: Optional[StorageType] = None):
        self.value = value
        self.type = type
        self.unit = unit
        self.description = description
        self.datatype = datatype

class Scalar(Statistic):
    """
    A scalar Python statistic type.
    """

    value: Union[float, int]

    def __init__(self, value: Any,
                 unit: Optional[str] = None,
                 description: Optional[str] = None,
                 datatype: Optional[StorageType] = None):
        super(Scalar, self).__init__(
                                     value=value,
                                     type="Scalar",
                                     unit=unit,
                                     description=description,
                                     datatype=datatype,
                                    )

class BaseScalarVector(Statistic):
    """
    An abstract base class for classes containing a vector of Scalar values.
    """
    value: List[Union[int,float]]

    def __init__(self, value: Iterable[Union[int,float]],
                 type: Optional[str] = None,
                 unit: Optional[str] = None,
                 description: Optional[str] = None,
                 datatype: Optional[StorageType] = None):
        super(BaseScalarVector, self).__init__(
                                           value=list(value),
                                           type=type,
                                           unit=unit,
                                           description=description,
                                           datatype=datatype,
                                           )

    def mean(self) -> float:
        """
        Returns the mean of the value vector.

        Returns
        -------
        float
            The mean value across all bins.
        """
        assert(self.value != None)
        assert(isinstance(self.value, List))

        from statistics import mean as statistics_mean
        return statistics_mean(self.value)

    def count(self) -> float:
        """
        Returns the count across all the bins.

        Returns
        -------
        float
            The sum of all bin values.
        """
        assert(self.value != None)
        return sum(self.value)


class Distribution(BaseScalarVector):
    """
    A statistic type that stores information relating to distributions. Each
    distribution has a number of bins (>=1)
    between this range. The values correspond to the value of each bin.
    E.g., value[3]` is the value of the 4th bin.

    It is assumed each bucket is of equal size.
    """

    min: Union[float, int]
    max: Union[float, int]
    num_bins: int
    bin_size: Union[float, int]
    sum: Optional[int]
    sum_squared: Optional[int]
    underflow: Optional[int]
    overflow: Optional[int]
    logs: Optional[float]

    def __init__(self, value: Iterable[int],
                 min: Union[float, int],
                 max: Union[float, int],
                 num_bins: int,
                 bin_size: Union[float, int],
                 sum: Optional[int] = None,
                 sum_squared: Optional[int] = None,
                 underflow: Optional[int] = None,
                 overflow: Optional[int] = None,
                 logs: Optional[float] = None,
                 unit: Optional[str] = None,
                 description: Optional[str] = None,
                 datatype: Optional[StorageType] = None):
        super(Distribution, self).__init__(
                                           value=value,
                                           type="Distribution",
                                           unit=unit,
                                           description=description,
                                           datatype=datatype,
                                           )

        self.min = min
        self.max = max
        self.num_bins = num_bins
        self.bin_size = bin_size
        self.sum = sum
        self.underflow = underflow
        self.overflow = overflow
        self.logs = logs
        self.sum_squared = sum_squared

        # These check some basic conditions of a distribution.
        assert(self.bin_size >= 0)
        assert(self.num_bins >= 1)

class Accumulator(BaseScalarVector):
    """
    A statistical type representing an accumulator.
    """

    _count: int
    min: Union[int, float]
    max: Union[int, float]
    sum_squared: Optional[int]

    def __init__(self, value: Iterable[Union[int,float]],
                 count: int,
                 min: Union[int, float],
                 max: Union[int, float],
                 sum_squared: Optional[int] = None,
                 unit: Optional[str] = None,
                 description: Optional[str] = None,
                 datatype: Optional[StorageType] = None):
        super(Accumulator, self).__init__(
                                     value=value,
                                     type="Accumulator",
                                     unit=unit,
                                     description=description,
                                     datatype=datatype,
                                    )

        self._count = count
        self.min = min
        self.max = max
        self.sum_squared = sum_squared

    def count(self) -> int:
        return self._count
