from copy import deepcopy
from datetime import timedelta, date
from typing import Union, Tuple, List

from dateutil import parser


def gen_date_series(days: int, timestamp_str: str) -> List[Tuple[date, None]]:
    """
    generate a list [ (date, None), ... ]
    values from DB will replace None in the list later

    :param days: number of days we want
    :param timestamp_str: start date
    :return: a list [ (date, None), ... ]
    """
    _date = parser.parse(timestamp_str).date() - timedelta(days=days - 1)
    return [(_date + timedelta(days=i), None) for i in range(days)]


def fill_series(date_series: List[Tuple[date, None]], fill: List[Tuple[date, Union[int, float, None]]]) \
        -> List[Tuple[date, Union[int, float, None]]]:
    """
    replace None in date_series with actual value, if exist in 'fill'

    :param date_series: date_series generated by gen_date_series()
    :param fill: return value of cursor.fetchall()
    :return: list [ (date, value), (date, None if not fetched from DB), ... ]
    """
    # noinspection Mypy
    result_series: List[Tuple[date, Union[int, float, None]]] = deepcopy(date_series)
    for fill_date, value in fill:
        for i, (tweet_date, _) in enumerate(result_series):
            if tweet_date == fill_date:
                result_series[i] = (tweet_date, value)
                break
    return result_series
