"""Tests for Kamereon API."""

import aiohttp
import pytest
from aiointercept import aiointercept
from syrupy.assertion import SnapshotAssertion
from yarl import URL

from tests import fixtures
from tests.const import TEST_ACCOUNT_ID
from tests.const import TEST_COUNTRY
from tests.const import TEST_KAMEREON_APIKEY
from tests.const import TEST_KAMEREON_URL
from tests.const import TEST_PERSON_ID
from tests.const import TEST_VIN

from renault_api import kamereon
from renault_api.kamereon import exceptions
from renault_api.kamereon import models


def test_vehicle_endpoints_sorted_by_key() -> None:
    """Ensure _VEHICLE_ENDPOINTS stays ordered by model code."""
    keys = list(models._VEHICLE_ENDPOINTS)
    assert keys == sorted(keys)

    for vehicle, endpoints in models._VEHICLE_ENDPOINTS.items():
        keys = list(endpoints)
        assert keys == sorted(keys), f"{vehicle} endpoints are not sorted: {keys}"


@pytest.mark.asyncio
async def test_get_person(
    websession: aiohttp.ClientSession, mocked_responses: aiointercept
) -> None:
    """Test get_person."""
    fixtures.inject_get_person(mocked_responses)

    person = await kamereon.get_person(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        person_id=TEST_PERSON_ID,
    )
    assert person.accounts is not None
    assert len(person.accounts) == 2


@pytest.mark.asyncio
async def test_get_account_vehicles(
    websession: aiohttp.ClientSession, mocked_responses: aiointercept
) -> None:
    """Test get_account_vehicles."""
    fixtures.inject_get_vehicles(mocked_responses, "zoe_40.1.json")

    await kamereon.get_account_vehicles(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
    )


@pytest.mark.asyncio
async def test_get_vehicle_data(
    websession: aiohttp.ClientSession, mocked_responses: aiointercept
) -> None:
    """Test get_vehicle_data."""
    fixtures.inject_get_battery_status(mocked_responses)

    assert await kamereon.get_vehicle_data(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
        vin=TEST_VIN,
        endpoint="battery-status",
    )


@pytest.mark.asyncio
async def test_get_vehicle_data_xml_bad_gateway(
    websession: aiohttp.ClientSession, mocked_responses: aiointercept
) -> None:
    """Test get_vehicle_data with invalid xml data."""
    fixtures.inject_get_battery_status(mocked_responses, "error/bad_gateway.html")

    with pytest.raises(exceptions.KamereonResponseException) as excinfo:
        await kamereon.get_vehicle_data(
            websession=websession,
            root_url=TEST_KAMEREON_URL,
            api_key=TEST_KAMEREON_APIKEY,
            gigya_jwt=fixtures.get_jwt(),
            country=TEST_COUNTRY,
            account_id=TEST_ACCOUNT_ID,
            vin=TEST_VIN,
            endpoint="battery-status",
        )
    assert excinfo.value.error_code == "Invalid JSON"
    assert excinfo.value.error_details
    assert excinfo.value.error_details.startswith(
        "<html>\n  <head>\n    <title>502 Bad Gateway</title>"
    )


@pytest.mark.asyncio
async def test_set_vehicle_action(
    websession: aiohttp.ClientSession,
    mocked_responses: aiointercept,
    snapshot: SnapshotAssertion,
) -> None:
    """Test set_vehicle_action."""
    url = fixtures.inject_set_hvac_start(mocked_responses, "cancel")
    assert await kamereon.set_vehicle_action(
        websession=websession,
        root_url=TEST_KAMEREON_URL,
        api_key=TEST_KAMEREON_APIKEY,
        gigya_jwt=fixtures.get_jwt(),
        country=TEST_COUNTRY,
        account_id=TEST_ACCOUNT_ID,
        vin=TEST_VIN,
        endpoint="hvac-start",
        attributes={"action": "cancel"},
    )

    request = mocked_responses.requests[("POST", URL(url))][0]
    assert request.kwargs["json"] == snapshot
