from __future__ import annotations

from contextlib import contextmanager
from unittest.mock import Mock

from app.core import db


def test_ensure_post_processing_active_job_unique_index_skips_when_index_exists(
    monkeypatch,
) -> None:
    connect_cm = Mock()
    connect_cm.__enter__ = Mock(return_value=object())
    connect_cm.__exit__ = Mock(return_value=None)

    monkeypatch.setattr(db.engine, "connect", Mock(return_value=connect_cm))
    monkeypatch.setattr(
        db.engine,
        "begin",
        Mock(side_effect=AssertionError("engine.begin() should not run")),
    )
    monkeypatch.setattr(db, "_index_exists", Mock(return_value=True))

    db._ensure_post_processing_active_job_unique_index()

    db.engine.connect.assert_called_once()
    db.engine.begin.assert_not_called()
    db._index_exists.assert_called_once()


def test_ensure_post_processing_active_job_unique_index_serializes_and_rechecks(
    monkeypatch,
) -> None:
    executed_sql: list[str] = []

    class FakeDuplicateResult:
        def first(self):
            return None

    class FakeScalarResult:
        def scalar(self):
            return None

    class FakeConnection:
        def execute(self, statement, params=None):  # noqa: ANN001
            sql = str(statement)
            executed_sql.append(sql)
            if "GROUP BY resource_type, resource_id, operation" in sql:
                return FakeDuplicateResult()
            return FakeScalarResult()

    @contextmanager
    def fake_connect():
        yield object()

    @contextmanager
    def fake_begin():
        yield FakeConnection()

    index_exists = Mock(side_effect=[False, False])

    monkeypatch.setattr(db.engine, "connect", fake_connect)
    monkeypatch.setattr(db.engine, "begin", fake_begin)
    monkeypatch.setattr(db, "_index_exists", index_exists)

    db._ensure_post_processing_active_job_unique_index()

    assert index_exists.call_count == 2
    assert any("pg_advisory_xact_lock" in sql for sql in executed_sql)
    assert any(
        "CREATE UNIQUE INDEX IF NOT EXISTS uq_post_processing_active_job" in sql
        for sql in executed_sql
    )


def test_ensure_post_processing_active_job_unique_index_skips_create_after_locked_recheck(
    monkeypatch,
) -> None:
    executed_sql: list[str] = []

    class FakeScalarResult:
        def scalar(self):
            return None

    class FakeConnection:
        def execute(self, statement, params=None):  # noqa: ANN001
            executed_sql.append(str(statement))
            return FakeScalarResult()

    @contextmanager
    def fake_connect():
        yield object()

    @contextmanager
    def fake_begin():
        yield FakeConnection()

    index_exists = Mock(side_effect=[False, True])

    monkeypatch.setattr(db.engine, "connect", fake_connect)
    monkeypatch.setattr(db.engine, "begin", fake_begin)
    monkeypatch.setattr(db, "_index_exists", index_exists)

    db._ensure_post_processing_active_job_unique_index()

    assert index_exists.call_count == 2
    assert any("pg_advisory_xact_lock" in sql for sql in executed_sql)
    assert not any(
        "CREATE UNIQUE INDEX IF NOT EXISTS uq_post_processing_active_job" in sql
        for sql in executed_sql
    )
