#!/usr/bin/python3

from datetime import datetime, timedelta

from ayla_iot_unofficial import (
    AylaApi,
    AylaAuthError,
    AylaNotAuthedError,
    AylaReadOnlyPropertyError,
    new_ayla_api,
)
from ayla_iot_unofficial.device import Device


def assert_raises(exc_type, func, *args, **kwargs):
    try:
        func(*args, **kwargs)
    except exc_type as exc:
        return exc
    raise AssertionError(f"{exc_type.__name__} was not raised")


api = new_ayla_api(
    "user@example.invalid",
    "password",
    "application-id",
    "application-secret",
)

assert isinstance(api, AylaApi)
assert api._email == "user@example.invalid"
assert api._password == "password"
assert api._app_id == "application-id"
assert api._app_secret == "application-secret"
assert api._access_token is None
assert api._refresh_token is None
assert api._auth_expiration is None
assert api._is_authed is False
assert api.websession is None

api._set_credentials(
    200,
    {
        "access_token": "access-token",
        "refresh_token": "refresh-token",
        "expires_in": 3600,
    },
)

assert api._is_authed is True
assert api._access_token == "access-token"
assert api._refresh_token == "refresh-token"
assert api.auth_expiration > datetime.now() + timedelta(seconds=3500)
assert api.auth_header == {"Authorization": "auth_token access-token"}

kwargs = {"headers": {"X-Test": "value"}}
assert api._get_headers(kwargs) == {
    "X-Test": "value",
    "Authorization": "auth_token access-token",
}
assert kwargs == {}

api._clear_auth()
assert_raises(AylaNotAuthedError, lambda: api.auth_header)

auth_exc = assert_raises(
    AylaAuthError,
    api._set_credentials,
    404,
    {"error": {"message": "Not found"}},
)
assert "app_id and app_secret" in str(auth_exc)

device = Device(
    api,
    {
        "dsn": "dsn-123",
        "key": 123,
        "oem_model": "OEM-1",
        "model": "MODEL-1",
        "mac": "00:11:22:33:44:55",
        "lan_ip": "192.0.2.10",
        "product_name": "Test device",
    },
)

assert device.name == "Test device"
assert device.serial_number == "dsn-123"
assert device.dsn_all_properties_endpoint.endswith("/apiv1/dsns/dsn-123/properties.json")
assert device.set_property_endpoint("target") == (
    "https://ads-field.aylanetworks.com/apiv1/dsns/dsn-123/properties/target/datapoints.json"
)

assert device._do_update(
    True,
    [
        {
            "property": {
                "name": "GET_status",
                "value": "1",
                "base_type": "integer",
                "read_only": True,
                "key": 1,
            }
        },
        {
            "property": {
                "name": "SET_target",
                "value": "21",
                "base_type": "integer",
                "read_only": False,
                "key": 2,
            }
        },
    ],
) is True

assert device.get_property_value("status") == 1
assert "target" in device._settable_properties
assert_raises(AylaReadOnlyPropertyError, device.set_property_value, "status", 0)
