# License: MIT
# Copyright © 2024 Frequenz Energy-as-a-Service GmbH

"""Resampler base types."""

from collections.abc import AsyncIterator, Callable, Coroutine
from dataclasses import dataclass
from datetime import datetime, timedelta

from frequenz.quantities import Quantity

from .._base_types import Sample

Source = AsyncIterator[Sample[Quantity]]
"""A source for a timeseries.

A timeseries can be received sample by sample in a streaming way
using a source.
"""

Sink = Callable[[Sample[Quantity]], Coroutine[None, None, None]]
"""A sink for a timeseries.

A new timeseries can be generated by sending samples to a sink.

This should be an `async` callable, for example:

```python
async some_sink(Sample) -> None:
    ...
```

Args:
    sample (Sample): A sample to be sent out.
"""


@dataclass
class SourceProperties:
    """Properties of a resampling source."""

    sampling_start: datetime | None = None
    """The time when resampling started for this source.

    `None` means it didn't started yet.
    """

    received_samples: int = 0
    """Total samples received by this source so far."""

    sampling_period: timedelta | None = None
    """The sampling period of this source.

    This means we receive (on average) one sample for this source every
    `sampling_period` time.

    `None` means it is unknown.
    """
