import itertools
from typing import Iterable, Iterator, Optional, TypeVar

T = TypeVar("T")


def window(
    iterator: Iterable[T], behind: int = 0, ahead: int = 0
) -> Iterator[tuple[Optional[T], ...]]:
    """
    Sliding window for an iterator.

    Example:
        >>> for prev, i, nxt in window(range(10), 1, 1):
        >>>     print(prev, i, nxt)

        None 0 1
        0 1 2
        1 2 3
        2 3 None
    """
    # TODO: move into utils
    iters: list[Iterator[Optional[T]]] = list(
        itertools.tee(iterator, behind + 1 + ahead)
    )
    for i in range(behind):
        iters[i] = itertools.chain((behind - i) * [None], iters[i])
    for i in range(ahead):
        iters[-1 - i] = itertools.islice(
            itertools.chain(iters[-1 - i], (ahead - i) * [None]), (ahead - i), None
        )
    return zip(*iters)
