import pytest

from app import main as main_module


@pytest.mark.asyncio
async def test_run_startup_calls_admin_bootstrap_before_logging_and_scheduler(monkeypatch):
    calls = []

    async def fake_init_db():
        calls.append('init_db')

    class DummySessionContext:
        async def __aenter__(self):
            calls.append('open_session')
            return object()

        async def __aexit__(self, exc_type, exc, tb):
            calls.append('close_session')

    async def fake_ensure_admin_user(session, settings):
        calls.append('ensure_admin_user')

    async def fake_persist_system_log(**kwargs):
        calls.append('persist_system_log')

    def fake_start_scheduler():
        calls.append('start_scheduler')

    monkeypatch.setattr(main_module, 'init_db', fake_init_db)
    monkeypatch.setattr(main_module, 'async_session', lambda: DummySessionContext())
    monkeypatch.setattr(main_module, 'ensure_admin_user', fake_ensure_admin_user)
    monkeypatch.setattr(main_module, 'persist_system_log', fake_persist_system_log)
    monkeypatch.setattr(main_module, 'start_scheduler', fake_start_scheduler)

    await main_module.run_startup()

    assert calls == [
        'init_db',
        'open_session',
        'ensure_admin_user',
        'close_session',
        'persist_system_log',
        'start_scheduler',
    ]


@pytest.mark.asyncio
async def test_run_startup_stops_before_logging_and_scheduler_when_admin_bootstrap_fails(monkeypatch):
    calls = []

    async def fake_init_db():
        calls.append('init_db')

    class DummySessionContext:
        async def __aenter__(self):
            calls.append('open_session')
            return object()

        async def __aexit__(self, exc_type, exc, tb):
            calls.append('close_session')

    async def fake_ensure_admin_user(session, settings):
        calls.append('ensure_admin_user')
        raise RuntimeError('bootstrap failed')

    async def fake_persist_system_log(**kwargs):
        calls.append('persist_system_log')

    def fake_start_scheduler():
        calls.append('start_scheduler')

    monkeypatch.setattr(main_module, 'init_db', fake_init_db)
    monkeypatch.setattr(main_module, 'async_session', lambda: DummySessionContext())
    monkeypatch.setattr(main_module, 'ensure_admin_user', fake_ensure_admin_user)
    monkeypatch.setattr(main_module, 'persist_system_log', fake_persist_system_log)
    monkeypatch.setattr(main_module, 'start_scheduler', fake_start_scheduler)

    with pytest.raises(RuntimeError, match='bootstrap failed'):
        await main_module.run_startup()

    assert calls == [
        'init_db',
        'open_session',
        'ensure_admin_user',
        'close_session',
    ]


@pytest.mark.asyncio
async def test_run_startup_rejects_default_secret_key_when_debug_is_disabled(monkeypatch):
    calls = []

    async def fake_init_db():
        calls.append('init_db')

    monkeypatch.setattr(main_module, 'init_db', fake_init_db)
    monkeypatch.setattr(main_module.settings, 'DEBUG', False)
    monkeypatch.setattr(main_module.settings, 'SECRET_KEY', 'change-me-in-production')

    with pytest.raises(RuntimeError, match='SECRET_KEY'):
        await main_module.run_startup()

    assert calls == []
