"""Standalone entrypoint для tradein-scraper контейнера (#1182).

Зачем: API-деплой (docker restart tradein-backend) не должен прерывать
бегущие scraper sweep'ы (avito/cian/rosreestr). Вынесен в отдельный
контейнер tradein-scraper с тем же backend-образом, но другой командой.

Запуск: python -m app.scheduler_main

Zombie-reap: reap_zombies() вызывается в начале каждого тика scheduler_loop()
(см. app/services/scheduler.py), дублировать здесь не нужно.
"""

from __future__ import annotations

import asyncio
import logging
import os
import signal
import sys
from contextlib import suppress

from app.core.config import settings

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)

logger = logging.getLogger(__name__)

# Мониторинг ошибок — GlitchTip (Sentry-совместимый, #396).
# Только integrations без Starlette/FastAPI (у нас нет ASGI-приложения здесь).
# SqlalchemyIntegration + HttpxIntegration + LoggingIntegration покрывают scraper-слой.
if settings.glitchtip_dsn:
    import sentry_sdk
    from sentry_sdk.integrations.httpx import HttpxIntegration
    from sentry_sdk.integrations.logging import LoggingIntegration
    from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

    from app.observability.sentry_scrub import scrub_pii_event

    sentry_sdk.init(
        dsn=settings.glitchtip_dsn,
        environment=settings.environment,
        release=os.getenv("GIT_SHA") or os.getenv("SENTRY_RELEASE") or "unknown",
        traces_sample_rate=0.0,
        send_default_pii=False,
        before_send=scrub_pii_event,
        integrations=[
            SqlalchemyIntegration(),
            HttpxIntegration(),
            LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
        ],
    )
    logger.info("GlitchTip monitoring enabled (scheduler_main)")


def _should_run() -> bool:
    """Проверить kill-switch SCHEDULER_ENABLE перед запуском asyncio loop."""
    return settings.scheduler_enable


async def _run() -> None:
    """Async entrypoint: запустить scheduler_loop() с чистой отменой по SIGTERM/SIGINT."""
    from app.services.scheduler import scheduler_loop

    task = asyncio.create_task(scheduler_loop())

    loop = asyncio.get_running_loop()

    def _cancel(_signum: int, _frame: object = None) -> None:
        logger.info("scheduler_main: signal received — cancelling scheduler task")
        task.cancel()

    try:
        loop.add_signal_handler(signal.SIGTERM, lambda: _cancel(signal.SIGTERM))
        loop.add_signal_handler(signal.SIGINT, lambda: _cancel(signal.SIGINT))
    except NotImplementedError:
        # Windows dev: signal handlers через loop не поддерживаются
        logger.warning("scheduler_main: loop.add_signal_handler not supported (Windows dev)")

    with suppress(asyncio.CancelledError):
        await task

    logger.info("scheduler_main: scheduler cancelled cleanly")


if __name__ == "__main__":
    if not _should_run():
        logger.warning("scheduler_main: scheduler disabled via SCHEDULER_ENABLE — exiting")
        sys.exit(0)

    # Best-effort FDW bootstrap: чтобы ensure_fdw_user_mapping отработал при старте
    # scraper-контейнера (postgres_fdw нужен для rosreestr_dkp_import).
    try:
        from app.core.db import SessionLocal
        from app.core.fdw import ensure_fdw_user_mapping

        with SessionLocal() as db:
            ensure_fdw_user_mapping(db)
    except Exception:
        logger.exception(
            "scheduler_main: FDW user mapping bootstrap failed — cadastral queries may fail"
        )

    asyncio.run(_run())
