from __future__ import annotations

import unittest
from contextlib import contextmanager
from types import SimpleNamespace
from unittest.mock import patch

from govoplan_core.celery_app import (
    celery,
    dispatch_mail_outbox,
    purge_mail_outbox,
)


class _Provider:
    def dispatch_due(self, session, **kwargs):
        return {"session": session, **kwargs}

    def purge_expired(self, session, **kwargs):
        return {"session": session, **kwargs}


class MailDeliveryWorkerTests(unittest.TestCase):
    def test_dispatch_uses_optional_provider_boundary(self) -> None:
        session = object()

        @contextmanager
        def session_scope():
            yield session

        database = SimpleNamespace(SessionLocal=session_scope)
        with (
            patch("govoplan_core.db.session.get_database", return_value=database),
            patch(
                "govoplan_core.celery_app._mail_delivery_outbox",
                return_value=_Provider(),
            ),
        ):
            result = dispatch_mail_outbox.run("tenant-1", 7)

        self.assertIs(result["session"], session)
        self.assertEqual(result["tenant_id"], "tenant-1")
        self.assertEqual(result["limit"], 7)

    def test_purge_uses_optional_provider_boundary(self) -> None:
        session = object()

        @contextmanager
        def session_scope():
            yield session

        database = SimpleNamespace(SessionLocal=session_scope)
        with (
            patch("govoplan_core.db.session.get_database", return_value=database),
            patch(
                "govoplan_core.celery_app._mail_delivery_outbox",
                return_value=_Provider(),
            ),
        ):
            result = purge_mail_outbox.run(19)

        self.assertIs(result["session"], session)
        self.assertEqual(result["limit"], 19)

    def test_worker_routes_and_schedules_are_declared(self) -> None:
        self.assertEqual(
            celery.conf.task_routes["govoplan.mail.dispatch_outbox"],
            {"queue": "mail"},
        )
        self.assertEqual(
            celery.conf.task_routes["govoplan.mail.purge_outbox"],
            {"queue": "mail"},
        )
        self.assertEqual(
            celery.conf.beat_schedule["mail-outbox-every-five-seconds"]["task"],
            "govoplan.mail.dispatch_outbox",
        )
        self.assertEqual(
            celery.conf.beat_schedule["mail-outbox-retention-daily"]["task"],
            "govoplan.mail.purge_outbox",
        )


if __name__ == "__main__":
    unittest.main()
