#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
Incremental user-defined aggregators for PySpark, the Python analog of Scala's
``org.apache.spark.sql.expressions.Aggregator``.
"""

from abc import ABC, abstractmethod
from typing import Any, Tuple

from pyspark.errors import PySparkNotImplementedError
from pyspark.sql.types import DataType, StructType

__all__ = ["Aggregator"]


class Aggregator(ABC):
    """
    Base class for a user-defined *incremental* aggregator, the Python analog of Scala's
    :class:`org.apache.spark.sql.expressions.Aggregator`.

    Unlike a grouped-aggregate ``pandas_udf`` (which materializes the whole group and is invoked
    once), an :class:`Aggregator` is executed as a genuine two-stage aggregation with map-side
    combine: :meth:`reduce` folds input rows into a per-group *buffer* on the map side, the buffers
    are shuffled by the grouping key, :meth:`merge` combines the partial buffers of each group, and
    :meth:`finish` produces the final output value.

    The buffer is represented as a Python :class:`tuple` whose elements correspond, in order, to the
    fields of :attr:`bufferSchema`. An input row is likewise a tuple of the argument values passed
    to the aggregator call. :meth:`merge` must be associative and commutative (the framework may
    combine partial buffers in any order), and :meth:`zero` must be its identity element -- see
    :meth:`zero` for the identity law that makes the result independent of the partition count.

    .. versionadded:: 4.4.0

    Examples
    --------
    A mean aggregator::

        from pyspark.sql.aggregator import Aggregator
        from pyspark.sql.functions import udaf
        from pyspark.sql.types import StructType, StructField, DoubleType, LongType

        class Mean(Aggregator):
            @property
            def bufferSchema(self):
                return StructType([
                    StructField("sum", DoubleType()),
                    StructField("count", LongType()),
                ])

            @property
            def outputType(self):
                return DoubleType()

            def zero(self):
                return (0.0, 0)

            def reduce(self, buffer, value):
                (v,) = value
                if v is None:  # ignore null inputs, like SQL aggregates do
                    return buffer
                return (buffer[0] + v, buffer[1] + 1)

            def merge(self, b1, b2):
                return (b1[0] + b2[0], b1[1] + b2[1])

            def finish(self, buffer):
                return buffer[0] / buffer[1] if buffer[1] else None

        mean = udaf(Mean())
        df.groupBy("k").agg(mean(df.v)).show()
    """

    @property
    @abstractmethod
    def bufferSchema(self) -> StructType:
        """The schema of the intermediate buffer that crosses the shuffle."""
        ...

    @property
    @abstractmethod
    def outputType(self) -> DataType:
        """The data type of the aggregator's output value."""
        ...

    @abstractmethod
    def zero(self) -> Tuple[Any, ...]:
        """The initial (identity) buffer value, as a tuple matching :attr:`bufferSchema`.

        This must be the identity element for :meth:`merge`::

            merge(buffer, zero()) == buffer
            merge(zero(), buffer) == buffer

        A fresh ``zero()`` seeds every partition -- and every early-flushed chunk of the map-side
        combine -- so associativity and commutativity of :meth:`merge` alone do not guarantee a
        partition-independent result; the identity law above is what makes the aggregate value
        independent of how the input is split across partitions and batches.
        """
        ...

    @abstractmethod
    def reduce(self, buffer: Tuple[Any, ...], value: Tuple[Any, ...]) -> Tuple[Any, ...]:
        """Fold a single input row ``value`` into ``buffer`` and return the updated buffer."""
        ...

    @abstractmethod
    def merge(self, buffer1: Tuple[Any, ...], buffer2: Tuple[Any, ...]) -> Tuple[Any, ...]:
        """Merge two partial buffers into one. Must be associative and commutative."""
        ...

    @abstractmethod
    def finish(self, buffer: Tuple[Any, ...]) -> Any:
        """Produce the output value from the final merged buffer."""
        ...

    # The aggregator instance is shipped to the worker as the UDF "function"; making it callable
    # lets it satisfy ``UserDefinedFunction``'s ``callable`` check. It is never actually invoked as
    # a function -- the worker calls :meth:`zero`/:meth:`reduce`/:meth:`merge`/:meth:`finish`.
    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        raise PySparkNotImplementedError(
            errorClass="NOT_IMPLEMENTED",
            messageParameters={"feature": "calling an Aggregator directly; wrap it with udaf(...)"},
        )
