from __future__ import annotations

import json
from uuid import uuid4

import pytest
from fastapi import BackgroundTasks, HTTPException
from starlette.requests import Request


def _request_with_json(payload: dict, headers: dict[str, str] | None = None) -> Request:
    body = json.dumps(payload).encode("utf-8")
    raw_headers = [
        (key.lower().encode("latin-1"), value.encode("latin-1"))
        for key, value in (headers or {}).items()
    ]

    async def receive() -> dict:
        return {"type": "http.request", "body": body, "more_body": False}

    return Request(
        {
            "type": "http",
            "method": "POST",
            "path": "/",
            "headers": raw_headers,
        },
        receive,
    )


def _operator_headers() -> dict[str, str]:
    return {
        "X-AwoooP-Operator-Id": "gitea-e2e-health",
        "X-AwoooP-Operator-Key": "secret",
    }


def _sentry_canary_payload() -> dict:
    return {
        "action": "triggered",
        "data": {
            "issue": {
                "id": "awoooi-canary-test-run",
                "shortId": "AWOOOI-CANARY",
                "title": "AwoooPSourceProviderCanary",
                "culprit": "source-provider-ingestion",
                "level": "info",
                "project": {"slug": "awoooi"},
            },
            "event": {
                "message": "AwoooP upstream source provider canary",
                "tags": [["awoooi_canary", "true"], ["run_ref", "test-run"]],
            },
        },
    }


@pytest.mark.asyncio
async def test_sentry_upstream_canary_records_without_signature(monkeypatch) -> None:
    from src.api.v1 import sentry_webhook
    from src.core.config import settings

    calls: list[dict] = []

    async def fake_record_external_alert_event(**kwargs):
        calls.append(kwargs)
        return uuid4()

    monkeypatch.setattr(settings, "ENVIRONMENT", "prod")
    monkeypatch.setattr(settings, "AWOOOP_OPERATOR_API_KEY", "secret")
    monkeypatch.setattr(
        sentry_webhook,
        "record_external_alert_event",
        fake_record_external_alert_event,
    )

    result = await sentry_webhook.handle_sentry_error(
        _request_with_json(_sentry_canary_payload(), _operator_headers()),
        BackgroundTasks(),
    )

    assert result["status"] == "canary_recorded"
    assert result["side_effects"] == {
        "incident_created": False,
        "approval_created": False,
        "telegram_sent": False,
        "openclaw_called": False,
    }
    assert calls[0]["provider"] == "sentry"
    assert calls[0]["stage"] == "upstream_canary"
    assert calls[0]["event_id"] == "awoooi-canary-test-run"
    assert calls[0]["labels"]["incident"] == "not_created"


@pytest.mark.asyncio
async def test_sentry_non_canary_still_requires_signature(monkeypatch) -> None:
    from src.api.v1 import sentry_webhook
    from src.core.config import settings

    monkeypatch.setattr(settings, "ENVIRONMENT", "prod")
    monkeypatch.setattr(settings, "SENTRY_WEBHOOK_SECRET", "required-secret")

    payload = _sentry_canary_payload()
    payload["data"]["issue"]["id"] = "real-issue-1"
    payload["data"]["issue"]["shortId"] = "REAL-1"
    payload["data"]["issue"]["title"] = "Real issue"
    payload["data"]["event"]["tags"] = []

    with pytest.raises(HTTPException) as exc_info:
        await sentry_webhook.handle_sentry_error(
            _request_with_json(payload, _operator_headers()),
            BackgroundTasks(),
        )

    assert exc_info.value.status_code == 401


@pytest.mark.asyncio
async def test_signoz_upstream_canary_records_without_incident_side_effects(monkeypatch) -> None:
    from src.api.v1 import signoz_webhook
    from src.core.config import settings

    calls: list[dict] = []

    async def fake_record_external_alert_event(**kwargs):
        calls.append(kwargs)
        return uuid4()

    monkeypatch.setattr(settings, "ENVIRONMENT", "prod")
    monkeypatch.setattr(settings, "AWOOOP_OPERATOR_API_KEY", "secret")
    monkeypatch.setattr(
        signoz_webhook,
        "record_external_alert_event",
        fake_record_external_alert_event,
    )
    payload = {
        "alerts": [
            {
                "status": "firing",
                "alertname": "AwoooPSourceProviderCanary",
                "labels": {
                    "alertname": "AwoooPSourceProviderCanary",
                    "severity": "info",
                    "namespace": "awoooi-prod",
                    "service": "source-provider-ingestion",
                    "awoooi_canary": "true",
                    "run_ref": "test-run",
                },
                "annotations": {"summary": "AwoooP upstream source provider canary"},
            }
        ]
    }

    result = await signoz_webhook.handle_signoz_alert(
        _request_with_json(payload, _operator_headers()),
        BackgroundTasks(),
    )

    assert result["status"] == "ok"
    assert result["results"][0]["status"] == "canary_recorded"
    assert result["results"][0]["side_effects"] == {
        "incident_created": False,
        "approval_created": False,
        "telegram_sent": False,
        "openclaw_called": False,
    }
    assert calls[0]["provider"] == "signoz"
    assert calls[0]["stage"] == "upstream_canary"
    assert calls[0]["labels"]["approval"] == "not_created"
