# encoding: utf-8
from datetime import timedelta, datetime

from grain import Grain

__copyright__ = "Copyright (C) 2015 University of Wisconsin SSEC. All rights reserved."

UNIX_EPOCH = datetime(1970, 1, 1)
CDS_EPOCH = datetime(1958, 1, 1)


def unixtime(dt):
    """
    Datetime to Unix timestamp.
    """
    return (dt - datetime(1970, 1, 1)).total_seconds()


def timecode_parts_to_dt(days, ms, us, epoch):
    """
    Convert components to a UTC datetime based on arbitrary epoch.
    """
    return epoch + timedelta(days=days, microseconds=1e3 * ms + us)


def timecode_parts_to_iet(days, ms, us, epoch):
    """
    Convert components to a IET based on arbitrary epoch.
    """
    return int(
        _get_grain().utc2tai(
            epoch
            + timedelta(
                days=float(days), milliseconds=float(ms), microseconds=float(us)
            ),
            epoch,
        )
        * 1e6
    )


def cds_to_iet(days, ms, us):
    """
    CCSDS Day Segmented timecode (UTC) parts to IET (microseconds)
    """
    return timecode_parts_to_iet(days, ms, us, CDS_EPOCH)


def cds_to_dt(days, ms, us):
    """
    CCSDS Day Segmented timecode to UTC datetime.
    """
    return timecode_parts_to_dt(days, ms, us, CDS_EPOCH)


def dt_to_cds(dt):
    """
    UTC datetime to (day, millis, micros)
    """
    d = dt - CDS_EPOCH
    return (d.days, int(d.seconds * 1e3), d.microseconds)


_grain = None


def _get_grain():
    global _grain
    if _grain is None:
        _grain = Grain()
    return _grain


def dt_to_iet(*args, **kwargs):
    return _get_grain().utc2iet(*args, **kwargs)


def iet_to_dt(*args, **kwargs):
    return _get_grain().iet2utc(*args, **kwargs)