"""S-1 초기 백필 — 기존 active study_topics 를 발행 outbox 에 1회 적재.

publish_outbox 에만 적재한다(멱등: 발행 워커의 (payload_hash, deleted) 디둡이
중복 enqueue 를 no-op 으로 흡수). study_publish_enabled=True 일 때 발행 워커가
1분 주기로 drain → published 에 rev 부여 → viewer pull-sync.

주제 수는 개인 학습툴이라 소량 — bounded page 사실상 1페이지지만 PAGE 도달 시
overflow 가드로 페이징 누락을 경보(silent truncation 금지).

실행 (GPU 서버):
  docker exec hyungi_document_server-fastapi-1 python /app/scripts/backfill_publish_topics.py
  # dry-run(적재 없이 카운트만):
  docker exec hyungi_document_server-fastapi-1 python /app/scripts/backfill_publish_topics.py --dry-run
"""

import argparse
import asyncio
import os
import sys

# fastapi 컨테이너 WORKDIR=/app — `from models...` import 가능하게 path 추가.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

# standalone-model-registry-fix: app(라우터 경유 전 모델 import)과 달리 script 는 부분 모델만
# import → SQLAlchemy mapper string 관계(StudyTopic.sessions->StudySession 등) 해소 실패.
# 전 모델 모듈 import 로 레지스트리 완성(전부 컨테이너서 import 가능 = app 이 기동 시 로드).
import importlib as _il, pkgutil as _pu
import models as _mp
for _m in _pu.iter_modules(_mp.__path__):
    _il.import_module("models." + _m.name)


from sqlalchemy import func, select

from core.config import settings
from core.database import async_session
from models.study_topic import StudyTopic
from services.study.publish_enqueue import backfill_publish_topics

# 개인 학습툴 주제 수 대비 넉넉. 도달 시 overflow 가드가 경보.
PAGE = 5000


async def run(dry_run: bool) -> None:
    async with async_session() as session:
        active = (
            await session.execute(
                select(func.count())
                .select_from(StudyTopic)
                .where(StudyTopic.deleted_at.is_(None))
            )
        ).scalar() or 0

    print(f"[info] study_publish_enabled={settings.study_publish_enabled} "
          f"(False 면 적재는 되나 워커가 drain 안 함)")
    print(f"[info] active 주제 {active}건")
    if dry_run:
        print("[dry-run] 적재 안 함. 실제 실행은 --dry-run 제거.")
        return

    async with async_session() as session:
        n = await backfill_publish_topics(session, after_id=0, limit=PAGE)
        await session.commit()

    print(f"\n[ok] outbox 적재 {n}건 — 발행 워커가 drain(flag on 시) 하며 rev 부여.")
    if n >= PAGE:
        print(f"[warn] PAGE({PAGE}) 도달 — 주제가 더 있을 수 있음. after_id 페이징 추가 필요.")


def main() -> None:
    parser = argparse.ArgumentParser(description="S-1 pub_topics 초기 백필")
    parser.add_argument("--dry-run", action="store_true", default=False)
    args = parser.parse_args()
    asyncio.run(run(args.dry_run))


if __name__ == "__main__":
    main()
