import json

import pytest

from app.models.stream_events import GraphArtifactReadyEvent
from app.repositories import embedding_run_repo
from app.services import stream_dispatch_service
from app.services.pipeline_service import run_snapshot_embedding_pipeline
from tests.integration.fakes import seed_snapshot_upstream


@pytest.mark.integration
@pytest.mark.asyncio
async def test_stream_dispatch_to_pipeline_end_to_end(integration_env):
    seed_snapshot_upstream(integration_env["db"])
    enqueued: list[tuple] = []

    class _Task:
        id = "celery-task-integration"

    def _delay(*args):
        enqueued.append(args)
        return _Task()

    event = GraphArtifactReadyEvent.model_validate(
        {
            "event_id": "evt_snap_abc123_graph_ready",
            "event_version": "v1",
            "repo_id": "AD/example-repo",
            "snapshot_id": "snap_abc123",
            "commit_sha": "a1b2c3d4e5f6",
            "artifact_id": "art_snap_abc123_merged",
            "artifact_uri": "mongo://snapshot_graphs/art_snap_abc123_merged",
        }
    )

    import app.services.stream_dispatch_service as dispatch_module

    dispatch_module.process_snapshot_embedding_task.delay = _delay
    try:
        first = await stream_dispatch_service.dispatch_graph_artifact_ready(event)
        second = await stream_dispatch_service.dispatch_graph_artifact_ready(event)

        assert first.skipped is False
        assert second.skipped is True
        assert len(enqueued) == 1

        run_id, repo_id, snapshot_id, commit_sha, artifact_uri, event_id = enqueued[0]
        await run_snapshot_embedding_pipeline(
            run_id=run_id,
            repo_id=repo_id,
            snapshot_id=snapshot_id,
            commit_sha=commit_sha,
            artifact_uri=artifact_uri,
            event_id=event_id,
        )
    finally:
        from app.workers import pipeline_tasks

        dispatch_module.process_snapshot_embedding_task.delay = (
            pipeline_tasks.process_snapshot_embedding_task.delay
        )

    run = await embedding_run_repo.get_run(first.run_id)
    assert run is not None
    assert run.celery_task_id == "celery-task-integration"
    assert len(integration_env["qdrant"].points) == 2
