
from typing import Optional

from datetime import datetime, date, timedelta

import rfc3339
import iso8601


def format_vars(*args, **kwargs):
    """
    method to shorten dubug ie
    log.info('message', extra=d(1))
    instead of
    log.info('message', extra={'v': 1})
    """
    return {'a': args, 'kwa': kwargs}


d = format_vars


def is_dt_naive(dt_value: datetime) -> bool:
    """ checks that datetime doesn't have tz information """
    return dt_value.tzinfo is None or dt_value.tzinfo.utcoffset(d) is None


def dt_to_rfc3339(dt_value: datetime) -> str:
    """
    reverse: iso8601.parse_date(date_string)
    """
    return rfc3339.rfc3339(dt_value)


def str_to_dt(dt_str: str) -> datetime:
    return iso8601.parse_date(dt_str)


def now():
    """ used mostly in tests, so timezone must be but it doesn't really matter """
    return datetime.utcnow()


def get_week_start_day(input_date: Optional[date] = None) -> date:
    """
    This function defines what is considered a week across all the projects. 
    So far the week start day is Sunday. So week of Synday date is the time range of 7 days starting Sunday and finishing Saturday
    """
    if input_date is None:
        input_date = date.today()
    return (input_date - timedelta(days=((input_date.weekday() + 1)) % 7))
