# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

from datetime import datetime, timezone
from typing import Optional

EPOCH_AS_FILETIME = 116444736000000000  # January 1, 1970 as MS filetime
HUNDREDS_OF_NANOSECONDS = 10000000


def _to_utc_datetime(value: datetime) -> str:
    return value.strftime('%Y-%m-%dT%H:%M:%SZ')


def _rfc_1123_to_datetime(rfc_1123: str) -> Optional[datetime]:
    """Converts an RFC 1123 date string to a UTC datetime.

    :param str rfc_1123: The time and date in RFC 1123 format.
    :returns: The time and date in UTC datetime format.
    :rtype: datetime
    """
    if not rfc_1123:
        return None

    return datetime.strptime(rfc_1123, "%a, %d %b %Y %H:%M:%S %Z")


def _filetime_to_datetime(filetime: str) -> Optional[datetime]:
    """Converts an MS filetime string to a UTC datetime. "0" indicates None.
    If parsing MS Filetime fails, tries RFC 1123 as backup.

    :param str filetime: The time and date in MS filetime format.
    :returns: The time and date in UTC datetime format.
    :rtype: datetime
    """
    if not filetime:
        return None

    # Try to convert to MS Filetime
    try:
        temp_filetime = int(filetime)
        if temp_filetime == 0:
            return None

        return datetime.fromtimestamp((temp_filetime - EPOCH_AS_FILETIME) / HUNDREDS_OF_NANOSECONDS, tz=timezone.utc)
    except ValueError:
        pass

    # Try RFC 1123 as backup
    return _rfc_1123_to_datetime(filetime)
