import datetime as _datetime

from collections.abc import Mapping
from typing import IO
from typing import Iterable
from typing import Tuple
from typing import Union

from ._utils import parse_rfc3339
from .container import Container
from .exceptions import UnexpectedCharError
from .items import AoT
from .items import Array
from .items import Bool
from .items import Comment
from .items import Date
from .items import DateTime
from .items import DottedKey
from .items import Float
from .items import InlineTable
from .items import Integer
from .items import Item as _Item
from .items import Key
from .items import SingleKey
from .items import String
from .items import Table
from .items import Time
from .items import Trivia
from .items import Whitespace
from .items import item
from .parser import Parser
from .toml_document import TOMLDocument


def loads(string: Union[str, bytes]) -> TOMLDocument:
    """
    Parses a string into a TOMLDocument.

    Alias for parse().
    """
    return parse(string)


def dumps(data: Mapping, sort_keys: bool = False) -> str:
    """
    Dumps a TOMLDocument into a string.
    """
    if not isinstance(data, Container) and isinstance(data, Mapping):
        data = item(dict(data), _sort_keys=sort_keys)

    try:
        # data should be a `Container` (and therefore implement `as_string`)
        # for all type safe invocations of this function
        return data.as_string()  # type: ignore[attr-defined]
    except AttributeError as ex:
        msg = f"Expecting Mapping or TOML Container, {type(data)} given"
        raise TypeError(msg) from ex


def load(fp: IO) -> TOMLDocument:
    """
    Load toml document from a file-like object.
    """
    return parse(fp.read())


def dump(data: Mapping, fp: IO[str], *, sort_keys: bool = False) -> None:
    """
    Dump a TOMLDocument into a writable file stream.

    :param data: a dict-like object to dump
    :param sort_keys: if true, sort the keys in alphabetic order
    """
    fp.write(dumps(data, sort_keys=sort_keys))


def parse(string: Union[str, bytes]) -> TOMLDocument:
    """
    Parses a string or bytes into a TOMLDocument.
    """
    return Parser(string).parse()


def document() -> TOMLDocument:
    """
    Returns a new TOMLDocument instance.
    """
    return TOMLDocument()


# Items
def integer(raw: Union[str, int]) -> Integer:
    """Create an integer item from a number or string."""
    return item(int(raw))


def float_(raw: Union[str, float]) -> Float:
    """Create an float item from a number or string."""
    return item(float(raw))


def boolean(raw: str) -> Bool:
    """Turn `true` or `false` into a boolean item."""
    return item(raw == "true")


def string(raw: str) -> String:
    """Create a string item."""
    return item(raw)


def date(raw: str) -> Date:
    """Create a TOML date."""
    value = parse_rfc3339(raw)
    if not isinstance(value, _datetime.date):
        raise ValueError("date() only accepts date strings.")

    return item(value)


def time(raw: str) -> Time:
    """Create a TOML time."""
    value = parse_rfc3339(raw)
    if not isinstance(value, _datetime.time):
        raise ValueError("time() only accepts time strings.")

    return item(value)


def datetime(raw: str) -> DateTime:
    """Create a TOML datetime."""
    value = parse_rfc3339(raw)
    if not isinstance(value, _datetime.datetime):
        raise ValueError("datetime() only accepts datetime strings.")

    return item(value)


def array(raw: str = None) -> Array:
    """Create an array item for its string representation.

    :Example:

    >>> array("[1, 2, 3]")  # Create from a string
    [1, 2, 3]
    >>> a = array()
    >>> a.extend([1, 2, 3])  # Create from a list
    >>> a
    [1, 2, 3]
    """
    if raw is None:
        raw = "[]"

    return value(raw)


def table(is_super_table: bool = False) -> Table:
    """Create an empty table.

    :param is_super_table: if true, the table is a super table

    :Example:

    >>> doc = document()
    >>> foo = table(True)
    >>> bar = table()
    >>> bar.update({'x': 1})
    >>> foo.append('bar', bar)
    >>> doc.append('foo', foo)
    >>> print(doc.as_string())
    [foo.bar]
    x = 1
    """
    return Table(Container(), Trivia(), False, is_super_table)


def inline_table() -> InlineTable:
    """Create an inline table.

    :Example:

    >>> table = inline_table()
    >>> table.update({'x': 1, 'y': 2})
    >>> print(table.as_string())
    {x = 1, y = 2}
    """
    return InlineTable(Container(), Trivia(), new=True)


def aot() -> AoT:
    """Create an array of table.

    :Example:

    >>> doc = document()
    >>> aot = aot()
    >>> aot.append(item({'x': 1}))
    >>> doc.append('foo', aot)
    >>> print(doc.as_string())
    [[foo]]
    x = 1
    """
    return AoT([])


def key(k: Union[str, Iterable[str]]) -> Key:
    """Create a key from a string. When a list of string is given,
    it will create a dotted key.

    :Example:

    >>> doc = document()
    >>> doc.append(key('foo'), 1)
    >>> doc.append(key(['bar', 'baz']), 2)
    >>> print(doc.as_string())
    foo = 1
    bar.baz = 2
    """
    if isinstance(k, str):
        return SingleKey(k)
    return DottedKey([key(_k) for _k in k])


def value(raw: str) -> _Item:
    """Parse a simple value from a string.

    :Example:

    >>> value("1")
    1
    >>> value("true")
    True
    >>> value("[1, 2, 3]")
    [1, 2, 3]
    """
    parser = Parser(raw)
    v = parser._parse_value()
    if not parser.end():
        raise parser.parse_error(UnexpectedCharError, char=parser._current)
    return v


def key_value(src: str) -> Tuple[Key, _Item]:
    """Parse a key-value pair from a string.

    :Example:

    >>> key_value("foo = 1")
    (Key('foo'), 1)
    """
    return Parser(src)._parse_key_value()


def ws(src: str) -> Whitespace:
    """Create a whitespace from a string."""
    return Whitespace(src, fixed=True)


def nl() -> Whitespace:
    """Create a newline item."""
    return ws("\n")


def comment(string: str) -> Comment:
    """Create a comment item."""
    return Comment(Trivia(comment_ws="  ", comment="# " + string))
