"""
Comparison of ISO 8601 timezone formats using Zulu (Z) and numeric offset (+hh:mm) notation.

UTC timezone:

- XmlDateTime.__str__()                 -> 2023-10-19T21:53:07.834537Z
- BaseModel.model_dump(mode="json")     -> 2023-10-19T21:53:07.834537Z
- datetime.datetime.isoformat()         -> 2023-10-19T21:53:07.834537+00:00

Non-UTC timezone:

- XmlDateTime.__str__()                 -> 2023-10-19T21:53:07.834537+02:00
- BaseModel.model_dump(mode="json")     -> 2023-10-19T21:53:07.834537+02:00
- datetime.datetime.isoformat()         -> 2023-10-19T21:53:07.834537+02:00
"""

import datetime
from typing import Union

from xsdata.models.datatype import XmlDateTime


def with_timezone_offset_format(dt: Union[XmlDateTime, datetime.datetime, str]) -> str:
    if isinstance(dt, str):
        dt = XmlDateTime.from_string(dt)
    if isinstance(dt, XmlDateTime):
        return dt.to_datetime().isoformat()
    if isinstance(dt, datetime.datetime):
        return dt.isoformat()
    raise TypeError(
        f"Expected XmlDateTime, datetime.datetime or str, got {type(dt).__name__}"
    )


def with_timezone_zulu_format(dt: Union[XmlDateTime, datetime.datetime, str]) -> str:
    if isinstance(dt, str):
        dt = XmlDateTime.from_string(dt)
    if isinstance(dt, XmlDateTime):
        return str(dt)
    if isinstance(dt, datetime.datetime):
        return str(XmlDateTime.from_datetime(dt))
    raise TypeError(
        f"Expected XmlDateTime, datetime.datetime or str, got {type(dt).__name__}"
    )


def deserialize_datetime(dt: str) -> datetime.datetime:
    # In CI at UTC python<=3.10 fromisoformat raises an exception for Zulu timezone format.
    # Since python 3.11 most ISO 8601 formats can be parsed.
    # https://docs.python.org/3/whatsnew/3.11.html#datetime
    return XmlDateTime.from_string(dt).to_datetime()
