import uuid
import enum
from typing import NamedTuple
from collections import namedtuple
from dataclasses import dataclass

import pytest

import aioinflux
from aioinflux import datapoint


class CpuLoad(enum.Enum):
    LOW = 10
    HIGH = 100


def test_decorator(sync_client):
    @datapoint
    class MyPoint(NamedTuple):
        measurement: aioinflux.MEASUREMENT
        time: aioinflux.TIMEINT
        host: aioinflux.TAG
        running: aioinflux.BOOL
        users: aioinflux.INT
        cpu_load: aioinflux.FLOAT
        cpu_load_level: aioinflux.ENUM
        cpu_load_level_tag: aioinflux.TAGENUM
        uuid: aioinflux.STR

    p = MyPoint(
        measurement="dp",
        time=1500,
        host="us1",
        running=True,
        users=1000,
        cpu_load=99.5,
        cpu_load_level=CpuLoad.HIGH,
        cpu_load_level_tag=CpuLoad.LOW,
        uuid=str(uuid.uuid4()),
    )
    assert p
    assert hasattr(p, 'to_lineprotocol')
    assert sync_client.write(p)
    print(sync_client.select_all('dp'))
    print(sync_client.query("SHOW FIELD KEYS FROM dp"))


def test_functional():
    schema = dict(
        measurement=aioinflux.MEASUREMENT,
        time=aioinflux.TIMEINT,
        host=aioinflux.TAG,
        running=aioinflux.BOOL,
        users=aioinflux.INT,
    )
    MyPoint = datapoint(namedtuple('MyPoint', schema.keys()), schema=schema)
    p = MyPoint("a", 2, "b", False, 5)
    print(p.to_lineprotocol())
    assert isinstance(p.to_lineprotocol(), bytes)


def test_datestr():
    schema = dict(
        measurement=aioinflux.MEASUREMENT,
        time=aioinflux.TIMESTR,
        host=aioinflux.TAG,
        running=aioinflux.BOOL,
        users=aioinflux.INT,
    )
    MyPoint = datapoint(namedtuple('MyPoint', schema.keys()), schema=schema)
    p = MyPoint("a", "2018-08-08 15:22:33", "b", False, 5)
    print(p.to_lineprotocol())
    assert isinstance(p.to_lineprotocol(), bytes)


def test_placeholder():
    @datapoint
    @dataclass
    class MyPoint:
        timestamp: aioinflux.TIMEINT
        _: aioinflux.PLACEHOLDER = True

    lp = MyPoint(0).to_lineprotocol()
    print(lp)


def test_extra_tags():
    @datapoint(extra_tags={'host': 'ap1'})
    class MyPoint(NamedTuple):
        measurement: aioinflux.MEASUREMENT
        time: aioinflux.TIMEINT
        running: aioinflux.BOOL
        users: aioinflux.INT

    p = MyPoint("a", 2, False, 5)
    assert b'ap1' in p.to_lineprotocol()


def test_rm_none():
    @datapoint(rm_none=True)
    class MyPoint(NamedTuple):
        measurement: aioinflux.MEASUREMENT
        time: aioinflux.TIMEINT
        host: aioinflux.TAG
        running: aioinflux.BOOL
        users: aioinflux.INT

    p = MyPoint("a", 2, "b", True, None)
    print(p.to_lineprotocol())
    assert b'users' not in p.to_lineprotocol()


def test_invalid_type():
    with pytest.raises(KeyError):
        @datapoint
        class MyPoint(NamedTuple):
            measurement: aioinflux.MEASUREMENT
            time: aioinflux.TIMEINT
            host: aioinflux.TAG
            running: bool
            users: aioinflux.INT

        assert MyPoint("a", 2, "b", None, 5)

    # noinspection PyArgumentList
    MyEnum = enum.Enum('MyEnum', names=list('ABC'))
    with pytest.raises(TypeError):
        @datapoint
        class MyPoint(NamedTuple):
            measurement: aioinflux.MEASUREMENT
            time: aioinflux.TIMEINT
            host: aioinflux.TAG
            running: MyEnum.A
            users: aioinflux.INT

        assert MyPoint("a", 2, "b", None, 5)

@@ -17,16 +17,46 @@
 rt enum%0A
+from datetime import datetime%0A
 from typ
@@ -1937,32 +1937,456 @@
 col(), bytes)%0A%0A%0A
+def test_datetime():%0A    schema = dict(%0A        measurement=aioinflux.MEASUREMENT,%0A        time=aioinflux.TIMEDT,%0A        host=aioinflux.TAG,%0A        running=aioinflux.BOOL,%0A        users=aioinflux.INT,%0A    )%0A    MyPoint = datapoint(namedtuple('MyPoint', schema.keys()), schema=schema)%0A    p = MyPoint(%22a%22, datetime.utcnow(), %22b%22, False, 5)%0A    print(p.to_lineprotocol())%0A    assert isinstance(p.to_lineprotocol(), bytes)%0A%0A%0A
 def test_placeho

Add test