import json
import logging

import pytest
import respx
from deepdiff import DeepDiff
from hypothesis import HealthCheck, Phase, given, settings
from hypothesis import strategies as st

from nextline_alert.emitter import Emitter


@respx.mock
@settings(
    phases=(Phase.generate,),
    suppress_health_check=[HealthCheck.function_scoped_fixture],
)
@given(
    platform=st.text(min_size=1, max_size=20),
    alertname=st.text(max_size=20),
    description=st.text(max_size=100),
    status_code=st.sampled_from([200, 500]),
)
async def test_property(
    caplog: pytest.LogCaptureFixture,
    platform: str,
    alertname: str,
    description: str,
    status_code: int,
) -> None:
    # NOTE: url generated by hypothesis.provisional.urls() didn't pass the test
    url = 'http://localhost:5000/alerts'

    respx.reset()  # As Hypothesis tests multiple times

    emit = Emitter(url=url, platform=platform)

    # Mock the HTTP POST request
    route = respx.post(url).respond(status_code=status_code)

    caplog.clear()
    with caplog.at_level(logging.ERROR):
        await emit(alertname=alertname, description=description)

    # Assert the log message
    records = [r for r in caplog.records if r.name == Emitter.__module__]
    if status_code == 200:
        assert not records
    else:
        assert len(records) == 1
        assert records[0].levelname == 'ERROR'
        assert 'Failed to emit alert' in records[0].message

    # Assert the HTTP POST request
    assert route.called
    assert len(route.calls) == 1
    call = route.calls[0]
    assert url == call.request.url

    data = json.loads(call.request.content)

    expected_data = {
        'status': 'firing',
        'alerts': [
            {
                'status': 'firing',
                'labels': {'alertname': alertname, 'platform': platform},
                'annotations': {'description': description, 'groups': 'nextline'},
            }
        ],
    }

    assert DeepDiff(data, expected_data) == {}
