"""Tests for retrieving information from the Elgato Key Light device."""

import json

import pytest
from aiohttp import ClientSession
from aioresponses import aioresponses

from elgato import Elgato, Info

from .conftest import load_fixture


async def test_info_key_light(responses: aioresponses) -> None:
    """Test getting Elgato Key Light device information."""
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=load_fixture("info-key-light.json"),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        info: Info = await elgato.info()
        assert info
        assert info.display_name == "Frenck"
        assert info.features == ["lights"]
        assert info.firmware_build_number == 218
        assert info.firmware_version == "1.0.3"
        assert info.hardware_board_type == 53
        assert info.mac_address == "AA:BB:CC:DD:EE:FF"
        assert info.product_name == "Elgato Key Light"
        assert info.serial_number == "CN11A1A00001"
        assert info.wifi
        assert info.wifi.frequency == 2400
        assert info.wifi.rssi == -48
        assert info.wifi.ssid == "Frenck-IoT"


async def test_info_key_light_air(responses: aioresponses) -> None:
    """Test getting Elgato Key Light Air device information."""
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=load_fixture("info-key-light-air.json"),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        info: Info = await elgato.info()
        assert info
        assert not info.display_name
        assert info.features == ["lights"]
        assert info.firmware_build_number == 195
        assert info.firmware_version == "1.0.3"
        assert info.hardware_board_type == 200
        assert info.mac_address is None
        assert info.product_name == "Elgato Key Light Air"
        assert info.serial_number == "CW44J2A03032"
        assert info.wifi is None


async def test_info_light_strip(responses: aioresponses) -> None:
    """Test getting Elgato Light Strip device information."""
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=load_fixture("info-light-strip.json"),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        info: Info = await elgato.info()
        assert info
        assert info.display_name == "Elgato Light"
        assert info.features == ["lights"]
        assert info.firmware_build_number == 211
        assert info.firmware_version == "1.0.4"
        assert info.hardware_board_type == 70
        assert info.mac_address is None
        assert info.product_name == "Elgato Light Strip"
        assert info.serial_number == "EW52J1A00082"
        assert info.wifi is None


async def test_change_display_name(responses: aioresponses) -> None:
    """Test changing the display name of an Elgato Light."""
    responses.put(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body="",
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        await elgato.display_name("OMG PUPPIES")


async def test_missing_display_name(responses: aioresponses) -> None:
    """Test ensure we can handle a missing display name."""
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=load_fixture("info-light-strip.json"),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        info: Info = await elgato.info()
        assert info
        assert info.display_name == "Elgato Light"


@pytest.mark.parametrize(
    ("fixture", "expected"),
    [
        ("info-key-light.json", "1"),
        ("info-key-light-mini.json", "0.1"),
        ("info-light-strip.json", None),
    ],
)
async def test_hardware_revision(
    responses: aioresponses,
    fixture: str,
    expected: str | None,
) -> None:
    """Test the hardware revision, which devices report in varying shapes.

    A Key Light sends the string "1", a Key Light Mini the number 0.1, and
    an older Light Strip does not send it at all.
    """
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=load_fixture(fixture),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        info = await elgato.info()

    assert info.hardware_revision == expected


@pytest.mark.parametrize(
    ("rssi", "expected"),
    [
        (-100, 0),
        (-90, 20),
        (-60, 80),
        (-50, 100),
        (-120, 0),
        (-10, 100),
    ],
)
async def test_wifi_signal_strength(
    responses: aioresponses,
    rssi: int,
    expected: int,
) -> None:
    """Test the Wi-Fi signal strength as a percentage.

    A device reports dBm, which nothing outside a spectrum analyzer reads
    comfortably. The scale runs from -100 dBm, which is nothing, to -50 dBm,
    which is as good as it gets.
    """
    info = json.loads(load_fixture("info-key-light.json"))
    info["wifi-info"]["rssi"] = rssi
    responses.get(
        "http://example.com:9123/elgato/accessory-info",
        status=200,
        body=json.dumps(info),
        content_type="application/json",
    )
    async with ClientSession() as session:
        elgato = Elgato("example.com", session=session)
        device_info = await elgato.info()

    assert device_info.wifi
    assert device_info.wifi.rssi == rssi
    assert device_info.wifi.signal_strength == expected
