from dateutil.parser import parse as parse_date
from datetime import timedelta

import pandas as pd


def _get_before_after(window: int):
    """
    Returns values for before and after in number of days, given a
    window length.
    """
    half, mod = window // 2, window % 2

    before = after = half

    if mod == 0:  # even window size
        after = max(0, after - 1)  # after >= 0

    return before, after


def _get_time_intervals(start, end, freq, before, after):

    start, end = parse_date(start), parse_date(end)

    date_range = pd.date_range(start=start + timedelta(days=before),
                               end=end,
                               freq=f'{freq}D')

    time_intervals = [[(t - timedelta(days=before)).strftime('%Y-%m-%d'),
                       (t + timedelta(days=after)).strftime('%Y-%m-%d')]
                      for t in date_range]

    return time_intervals, [t.strftime('%Y-%m-%d') for t in date_range]


def get_composite_intervals(start, end, freq, window=None):
    """
    Get compositing intervals and labels for performing
    manual compositing in OpenEO.

    Parameters
    ----------

    start : str or datetime
        start date for the new composites dates
    end : str or datetime
        end date for the new composites dates
    freq : int
        days interval for new dates array
    window : int
        moving window size in days on which the compositing function is applied

    Return
    ----------
    Tuple compositing intervals and composite time labels
    """

    window = window if window is not None else freq

    if window < freq:
        raise ValueError('`window` value should be equal or greater than '
                         '`freq` value.')

    before, after = _get_before_after(window)
    intervals, labels = _get_time_intervals(start, end, freq, before, after)

    return intervals, labels


if __name__ == '__main__':
    get_composite_intervals('2020-01-01', '2020-12-31', 10)
