from contextlib import suppress
from functools import lru_cache
from fastapi import APIRouter, Depends
from maur.api import raise_on_unauthenticated
from maur.grafana.loki_client import LokiClient
from maur.grafana.schemas import GrafanaWebhookPayload

from maur.components import worker_tasks
from maur.grafana.settings import GrafanaSettings
from maur.models import CodingTask
from maur.worker import CodingTaskMessage
from maur.repos import CodingTaskRepoDep, DuplicateTaskError


router = APIRouter()

@lru_cache
def grafana_settings() -> GrafanaSettings:
    return GrafanaSettings.from_env()

@lru_cache
def loki_client() -> LokiClient:
    return LokiClient()


@router.post(
    "/webhook",
    dependencies=[Depends(raise_on_unauthenticated)]
)
async def grafana_webook(
    body: GrafanaWebhookPayload,
    tasks: CodingTaskRepoDep
) -> dict[str, bool]:

    if not body.is_firing:
        return {"ok": True}

    settings = grafana_settings()

    for alert in body.alerts:
        if not alert.is_firing:
            continue

        if settings.match_labels:
            should_skip = False

            for label, value in settings.match_labels.items():
                 if alert.labels.get(label) != value:
                    should_skip = True
                    break

            if should_skip:
                continue


        tracebacks = None
        with suppress(Exception):
            tracebacks = await loki_client().logs_for_alert(alert)

        with suppress(DuplicateTaskError):
            task = await tasks.insert(
                CodingTask(
                    source="grafana",
                    source_id=alert.fingerprint,
                    repo_branch=settings.repo_branch,
                    prompt=settings.prompt_template.format(
                        body=body,
                        alert=alert,
                        tracebacks=tracebacks
                    )
                )
            )
            await worker_tasks.publish(CodingTaskMessage(task_id=task.id))

    return {"ok": True}

