"""Tests for history_sync task registration."""

from __future__ import annotations

from unittest.mock import AsyncMock, MagicMock, patch

from app.tasks import history_sync


class TestHistorySyncTask:
    async def test_register_schedules_job(self) -> None:
        fake_scheduler = MagicMock()
        class FakeState:
            pass

        class FakeSettings:
            fail2ban_socket = "/tmp/fake.sock"

        app = type("FakeApp", (), {})()
        app.state = FakeState()
        app.state.scheduler = fake_scheduler
        app.state.settings = FakeSettings()

        history_sync.register(app)

        fake_scheduler.add_job.assert_called_once()
        called_args, called_kwargs = fake_scheduler.add_job.call_args
        assert called_kwargs["id"] == history_sync.JOB_ID
        assert called_kwargs["kwargs"]["app"] == app

    async def test_backfill_window_is_7_5_days(self) -> None:
        assert history_sync.BACKFILL_WINDOW == 648000

    async def test_sync_uses_strict_since_after_restart(self) -> None:
        fake_app = type("FakeApp", (), {})()
        fake_app.state = type("FakeState", (), {})()
        fake_app.state.settings = type("FakeSettings", (), {})()
        fake_app.state.settings.fail2ban_socket = "/tmp/fake.sock"

        fake_app.state.db = MagicMock()

        async def fake_get_history_page(*, db_path: str, since: int, page: int, page_size: int, **kwargs):
            assert since == 1001
            return [], 0

        async def fake_get_fail2ban_db_path(socket_path: str) -> str:
            return "/tmp/fake.sqlite3"

        with patch(
            "app.tasks.history_sync._get_last_archive_ts",
            new=AsyncMock(return_value=1000),
        ), patch(
            "app.tasks.history_sync.get_fail2ban_db_path",
            new=fake_get_fail2ban_db_path,
        ), patch(
            "app.tasks.history_sync.fail2ban_db_repo.get_history_page",
            new=fake_get_history_page,
        ):
            await history_sync._run_sync(fake_app)
