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

"""Windowing concepts.

A WindowInto transform logically divides up or groups the elements of a
PCollection into finite windows according to a windowing function (derived from
WindowFn).

The output of WindowInto contains the same elements as input, but they have been
logically assigned to windows. The next GroupByKey(s) transforms, including one
within a composite transform, will group by the combination of keys and windows.

Windowing a PCollection allows chunks of it to be processed individually, before
the entire PCollection is available.  This is especially important for
PCollection(s) with unbounded size, since the full PCollection is never
available at once, since more data is continually arriving. For PCollection(s)
with a bounded size (aka. conventional batch mode), by default, all data is
implicitly in a single window (see GlobalWindows), unless WindowInto is
applied.

For example, a simple form of windowing divides up the data into fixed-width
time intervals, using FixedWindows.

Seconds are used as the time unit for the built-in windowing primitives here.
Integer or floating point seconds can be passed to these primitives.

Internally, seconds, with microsecond granularity, are stored as
timeutil.Timestamp and timeutil.Duration objects. This is done to avoid
precision errors that would occur with floating point representations.

Custom windowing function classes can be created, by subclassing from
WindowFn.
"""

# pytype: skip-file

import abc
from collections.abc import Iterable
from functools import total_ordering
from typing import Any
from typing import Generic
from typing import Optional
from typing import TypeVar

from google.protobuf import duration_pb2
from google.protobuf import timestamp_pb2

from apache_beam.coders import coders
from apache_beam.portability import common_urns
from apache_beam.portability import python_urns
from apache_beam.portability.api import beam_runner_api_pb2
from apache_beam.portability.api import standard_window_fns_pb2
from apache_beam.transforms import timeutil
from apache_beam.utils import proto_utils
from apache_beam.utils import urns
from apache_beam.utils import windowed_value
from apache_beam.utils.timestamp import MIN_TIMESTAMP
from apache_beam.utils.timestamp import Duration
from apache_beam.utils.timestamp import DurationTypes  # pylint: disable=unused-import
from apache_beam.utils.timestamp import Timestamp
from apache_beam.utils.timestamp import TimestampTypes  # pylint: disable=unused-import
from apache_beam.utils.windowed_value import WindowedValue

__all__ = [
    'TimestampCombiner',
    'WindowFn',
    'BoundedWindow',
    'IntervalWindow',
    'TimestampedValue',
    'GlobalWindow',
    'NonMergingWindowFn',
    'GlobalWindows',
    'FixedWindows',
    'SlidingWindows',
    'Sessions',
]


# TODO(ccy): revisit naming and semantics once Java Apache Beam finalizes their
# behavior.
class TimestampCombiner(object):
  """Determines how output timestamps of grouping operations are assigned."""

  OUTPUT_AT_EOW = beam_runner_api_pb2.OutputTime.END_OF_WINDOW
  OUTPUT_AT_EARLIEST = beam_runner_api_pb2.OutputTime.EARLIEST_IN_PANE
  OUTPUT_AT_LATEST = beam_runner_api_pb2.OutputTime.LATEST_IN_PANE
  # TODO(robertwb): Add this to the runner API or remove it.
  OUTPUT_AT_EARLIEST_TRANSFORMED = 'OUTPUT_AT_EARLIEST_TRANSFORMED'

  @staticmethod
  def get_impl(
      timestamp_combiner: beam_runner_api_pb2.OutputTime.Enum,
      window_fn: 'WindowFn') -> timeutil.TimestampCombinerImpl:
    if timestamp_combiner == TimestampCombiner.OUTPUT_AT_EOW:
      return timeutil.OutputAtEndOfWindowImpl()
    elif timestamp_combiner == TimestampCombiner.OUTPUT_AT_EARLIEST:
      return timeutil.OutputAtEarliestInputTimestampImpl()
    elif timestamp_combiner == TimestampCombiner.OUTPUT_AT_LATEST:
      return timeutil.OutputAtLatestInputTimestampImpl()
    elif timestamp_combiner == TimestampCombiner.OUTPUT_AT_EARLIEST_TRANSFORMED:
      return timeutil.OutputAtEarliestTransformedInputTimestampImpl(window_fn)
    else:
      raise ValueError('Invalid TimestampCombiner: %s.' % timestamp_combiner)


class WindowFn(urns.RunnerApiFn, metaclass=abc.ABCMeta):
  """An abstract windowing function defining a basic assign and merge."""
  class AssignContext(object):
    """Context passed to WindowFn.assign()."""
    def __init__(
        self,
        timestamp: TimestampTypes,
        element: Optional[Any] = None,
        window: Optional['BoundedWindow'] = None) -> None:
      self.timestamp = Timestamp.of(timestamp)
      self.element = element
      self.window = window

  @abc.abstractmethod
  def assign(self,
             assign_context: 'AssignContext') -> Iterable['BoundedWindow']:
    # noqa: F821

    """Associates windows to an element.

    Arguments:
      assign_context: Instance of AssignContext.

    Returns:
      An iterable of BoundedWindow.
    """
    raise NotImplementedError

  class MergeContext(object):
    """Context passed to WindowFn.merge() to perform merging, if any."""
    def __init__(self, windows: Iterable['BoundedWindow']) -> None:
      self.windows = list(windows)

    def merge(
        self,
        to_be_merged: Iterable['BoundedWindow'],
        merge_result: 'BoundedWindow') -> None:
      raise NotImplementedError

  @abc.abstractmethod
  def merge(self, merge_context: 'WindowFn.MergeContext') -> None:
    """Returns a window that is the result of merging a set of windows."""
    raise NotImplementedError

  def is_merging(self) -> bool:
    """Returns whether this WindowFn merges windows."""
    return True

  @abc.abstractmethod
  def get_window_coder(self) -> coders.Coder:
    raise NotImplementedError

  def get_transformed_output_time(
      self, window: 'BoundedWindow', input_timestamp: Timestamp) -> Timestamp:  # pylint: disable=unused-argument
    """Given input time and output window, returns output time for window.

    If TimestampCombiner.OUTPUT_AT_EARLIEST_TRANSFORMED is used in the
    Windowing, the output timestamp for the given window will be the earliest
    of the timestamps returned by get_transformed_output_time() for elements
    of the window.

    Arguments:
      window: Output window of element.
      input_timestamp: Input timestamp of element as a timeutil.Timestamp
        object.

    Returns:
      Transformed timestamp.
    """
    # By default, just return the input timestamp.
    return input_timestamp

  urns.RunnerApiFn.register_pickle_urn(python_urns.PICKLED_WINDOWFN)


class BoundedWindow(object):
  """A window for timestamps in range (-infinity, end).

  Attributes:
    end: End of window.
  """
  def __init__(self, end: TimestampTypes) -> None:
    self._end = Timestamp.of(end)

  @property
  def start(self) -> Timestamp:
    raise NotImplementedError

  @property
  def end(self) -> Timestamp:
    return self._end

  def max_timestamp(self) -> Timestamp:
    return self.end.predecessor()

  def __eq__(self, other):
    raise NotImplementedError

  def __ne__(self, other):
    #  Order first by endpoint, then arbitrarily
    return self.end != other.end or hash(self) != hash(other)

  def __lt__(self, other):
    if self.end != other.end:
      return self.end < other.end
    return hash(self) < hash(other)

  def __le__(self, other):
    if self.end != other.end:
      return self.end <= other.end
    return hash(self) <= hash(other)

  def __gt__(self, other):
    if self.end != other.end:
      return self.end > other.end
    return hash(self) > hash(other)

  def __ge__(self, other):
    if self.end != other.end:
      return self.end >= other.end
    return hash(self) >= hash(other)

  def __hash__(self):
    raise NotImplementedError

  def __repr__(self):
    return '[?, %s)' % float(self.end)


@total_ordering
class IntervalWindow(windowed_value._IntervalWindowBase, BoundedWindow):
  """A window for timestamps in range [start, end).

  Attributes:
    start: Start of window as seconds since Unix epoch.
    end: End of window as seconds since Unix epoch.
  """
  def __lt__(self, other):
    if self.end != other.end:
      return self.end < other.end
    return hash(self) < hash(other)

  def intersects(self, other: 'IntervalWindow') -> bool:
    return other.start < self.end or self.start < other.end

  def union(self, other: 'IntervalWindow') -> 'IntervalWindow':
    return IntervalWindow(
        min(self.start, other.start), max(self.end, other.end))


V = TypeVar("V")


@total_ordering
class TimestampedValue(Generic[V]):
  """A timestamped value having a value and a timestamp.

  Attributes:
    value: The underlying value.
    timestamp: Timestamp associated with the value as seconds since Unix epoch.
  """
  def __init__(self, value: V, timestamp: TimestampTypes) -> None:
    self.value = value
    self.timestamp = Timestamp.of(timestamp)

  def __eq__(self, other):
    return (
        type(self) == type(other) and self.value == other.value and
        self.timestamp == other.timestamp)

  def __hash__(self):
    return hash((self.value, self.timestamp))

  def __lt__(self, other):
    if type(self) != type(other):
      return type(self).__name__ < type(other).__name__
    if self.value != other.value:
      return self.value < other.value
    return self.timestamp < other.timestamp


class GlobalWindow(BoundedWindow):
  """The default window into which all data is placed (via GlobalWindows)."""
  _instance: Optional['GlobalWindow'] = None

  def __new__(cls):
    if cls._instance is None:
      cls._instance = super(GlobalWindow, cls).__new__(cls)
    return cls._instance

  def __init__(self) -> None:
    super().__init__(GlobalWindow._getTimestampFromProto())

  def __repr__(self):
    return 'GlobalWindow'

  def __hash__(self):
    return hash(type(self))

  def __eq__(self, other):
    # Global windows are always and only equal to each other.
    return self is other or type(self) is type(other)

  @property
  def start(self) -> Timestamp:
    return MIN_TIMESTAMP

  @staticmethod
  def _getTimestampFromProto() -> Timestamp:
    ts_millis = int(
        common_urns.constants.GLOBAL_WINDOW_MAX_TIMESTAMP_MILLIS.constant)
    return Timestamp(micros=ts_millis * 1000)


class NonMergingWindowFn(WindowFn):
  def is_merging(self) -> bool:
    return False

  def merge(self, merge_context: WindowFn.MergeContext) -> None:
    pass  # No merging.


class GlobalWindows(NonMergingWindowFn):
  """A windowing function that assigns everything to one global window."""
  @classmethod
  def windowed_batch(
      cls,
      batch: Any,
      timestamp: Timestamp = MIN_TIMESTAMP,
      pane_info: windowed_value.PaneInfo = windowed_value.PANE_INFO_UNKNOWN
  ) -> windowed_value.WindowedBatch:
    return windowed_value.HomogeneousWindowedBatch.of(
        batch, timestamp, (GlobalWindow(), ), pane_info)

  @classmethod
  def windowed_value(
      cls,
      value: Any,
      timestamp: Timestamp = MIN_TIMESTAMP,
      pane_info: windowed_value.PaneInfo = windowed_value.PANE_INFO_UNKNOWN
  ) -> WindowedValue:
    return WindowedValue(value, timestamp, (GlobalWindow(), ), pane_info)

  @classmethod
  def windowed_value_at_end_of_window(cls, value):
    return cls.windowed_value(value, GlobalWindow().max_timestamp())

  def assign(self,
             assign_context: WindowFn.AssignContext) -> list[GlobalWindow]:
    return [GlobalWindow()]

  def get_window_coder(self) -> coders.GlobalWindowCoder:
    return coders.GlobalWindowCoder()

  def __hash__(self):
    return hash(type(self))

  def __eq__(self, other):
    # Global windowfn is always and only equal to each other.
    return self is other or type(self) is type(other)

  def to_runner_api_parameter(self, context):
    return common_urns.global_windows.urn, None

  @staticmethod
  @urns.RunnerApiFn.register_urn(common_urns.global_windows.urn, None)
  def from_runner_api_parameter(
      unused_fn_parameter, unused_context) -> 'GlobalWindows':
    return GlobalWindows()


class FixedWindows(NonMergingWindowFn):
  """A windowing function that assigns each element to one time interval.

  The attributes size and offset determine in what time interval a timestamp
  will be slotted. The time intervals have the following formula:
  [N * size + offset, (N + 1) * size + offset)

  Attributes:
    size: Size of the window as seconds.
    offset: Offset of this window as seconds. Windows start at
      t=N * size + offset where t=0 is the UNIX epoch. The offset must be a
      value in range [0, size). If it is not it will be normalized to this
      range.
  """
  def __init__(self, size: DurationTypes, offset: TimestampTypes = 0):
    """Initialize a ``FixedWindows`` function for a given size and offset.

    Args:
      size (int): Size of the window in seconds.
      offset(int): Offset of this window as seconds. Windows start at
        t=N * size + offset where t=0 is the UNIX epoch. The offset must be a
        value in range [0, size). If it is not it will be normalized to this
        range.
    """
    if size <= 0:
      raise ValueError('The size parameter must be strictly positive.')
    self.size = Duration.of(size)
    self.offset = Timestamp.of(offset) % self.size

  def assign(self, context: WindowFn.AssignContext) -> list[IntervalWindow]:
    timestamp = context.timestamp
    start = timestamp - (timestamp - self.offset) % self.size
    return [IntervalWindow(start, start + self.size)]

  def get_window_coder(self) -> coders.IntervalWindowCoder:
    return coders.IntervalWindowCoder()

  def __eq__(self, other):
    if type(self) == type(other) == FixedWindows:
      return self.size == other.size and self.offset == other.offset

  def __hash__(self):
    return hash((self.size, self.offset))

  def to_runner_api_parameter(self, context):
    return (
        common_urns.fixed_windows.urn,
        standard_window_fns_pb2.FixedWindowsPayload(
            size=proto_utils.from_micros(
                duration_pb2.Duration, self.size.micros),
            offset=proto_utils.from_micros(
                timestamp_pb2.Timestamp, self.offset.micros)))

  @staticmethod
  @urns.RunnerApiFn.register_urn(
      common_urns.fixed_windows.urn,
      standard_window_fns_pb2.FixedWindowsPayload)
  def from_runner_api_parameter(fn_parameter, unused_context) -> 'FixedWindows':
    return FixedWindows(
        size=Duration(micros=proto_utils.to_micros(fn_parameter.size)),
        offset=Timestamp(micros=proto_utils.to_micros(fn_parameter.offset)))


class SlidingWindows(NonMergingWindowFn):
  """A windowing function that assigns each element to a set of sliding windows.

  The attributes size and offset determine in what time interval a timestamp
  will be slotted. The time intervals have the following formula:
  [N * period + offset, N * period + offset + size)

  Attributes:
    size: Size of the window as seconds.
    period: Period of the windows as seconds.
    offset: Offset of this window as seconds since Unix epoch. Windows start at
      t=N * period + offset where t=0 is the epoch. The offset must be a value
      in range [0, period). If it is not it will be normalized to this range.
  """
  def __init__(
      self,
      size: DurationTypes,
      period: DurationTypes,
      offset: TimestampTypes = 0,
  ):
    if size <= 0:
      raise ValueError('The size parameter must be strictly positive.')
    self.size = Duration.of(size)
    self.period = Duration.of(period)
    self.offset = Timestamp.of(offset) % period

  def assign(self, context: WindowFn.AssignContext) -> list[IntervalWindow]:
    timestamp = context.timestamp
    start = timestamp - ((timestamp - self.offset) % self.period)
    return [
        IntervalWindow(
            (interval_start := Timestamp(micros=s)),
            interval_start + self.size,
        ) for s in range(
            start.micros, timestamp.micros -
            self.size.micros, -self.period.micros)
    ]

  def get_window_coder(self) -> coders.IntervalWindowCoder:
    return coders.IntervalWindowCoder()

  def __eq__(self, other):
    if type(self) == type(other) == SlidingWindows:
      return (
          self.size == other.size and self.offset == other.offset and
          self.period == other.period)

  def __hash__(self):
    return hash((self.offset, self.period))

  def to_runner_api_parameter(self, context):
    return (
        common_urns.sliding_windows.urn,
        standard_window_fns_pb2.SlidingWindowsPayload(
            size=proto_utils.from_micros(
                duration_pb2.Duration, self.size.micros),
            offset=proto_utils.from_micros(
                timestamp_pb2.Timestamp, self.offset.micros),
            period=proto_utils.from_micros(
                duration_pb2.Duration, self.period.micros)))

  @staticmethod
  @urns.RunnerApiFn.register_urn(
      common_urns.sliding_windows.urn,
      standard_window_fns_pb2.SlidingWindowsPayload)
  def from_runner_api_parameter(
      fn_parameter, unused_context) -> 'SlidingWindows':
    return SlidingWindows(
        size=Duration(micros=proto_utils.to_micros(fn_parameter.size)),
        offset=Timestamp(micros=proto_utils.to_micros(fn_parameter.offset)),
        period=Duration(micros=proto_utils.to_micros(fn_parameter.period)))


class Sessions(WindowFn):
  """A windowing function that groups elements into sessions.

  A session is defined as a series of consecutive events
  separated by a specified gap size.

  Attributes:
    gap_size: Size of the gap between windows as floating-point seconds.
  """
  def __init__(self, gap_size: DurationTypes) -> None:
    if gap_size <= 0:
      raise ValueError('The size parameter must be strictly positive.')
    self.gap_size = Duration.of(gap_size)

  def assign(self, context: WindowFn.AssignContext) -> list[IntervalWindow]:
    timestamp = context.timestamp
    return [IntervalWindow(timestamp, timestamp + self.gap_size)]

  def get_window_coder(self) -> coders.IntervalWindowCoder:
    return coders.IntervalWindowCoder()

  def merge(self, merge_context: WindowFn.MergeContext) -> None:
    to_merge: list[BoundedWindow] = []
    end = MIN_TIMESTAMP
    for w in sorted(merge_context.windows, key=lambda w: w.start):
      if to_merge:
        if end > w.start:
          to_merge.append(w)
          if w.end > end:
            end = w.end
        else:
          if len(to_merge) > 1:
            merge_context.merge(
                to_merge, IntervalWindow(to_merge[0].start, end))
          to_merge = [w]
          end = w.end
      else:
        to_merge = [w]
        end = w.end
    if len(to_merge) > 1:
      merge_context.merge(to_merge, IntervalWindow(to_merge[0].start, end))

  def __eq__(self, other):
    if type(self) == type(other) == Sessions:
      return self.gap_size == other.gap_size

  def __hash__(self):
    return hash(self.gap_size)

  def to_runner_api_parameter(self, context):
    return (
        common_urns.session_windows.urn,
        standard_window_fns_pb2.SessionWindowsPayload(
            gap_size=proto_utils.from_micros(
                duration_pb2.Duration, self.gap_size.micros)))

  @staticmethod
  @urns.RunnerApiFn.register_urn(
      common_urns.session_windows.urn,
      standard_window_fns_pb2.SessionWindowsPayload)
  def from_runner_api_parameter(fn_parameter, unused_context) -> 'Sessions':
    return Sessions(
        gap_size=Duration(micros=proto_utils.to_micros(fn_parameter.gap_size)))
