"""PostgreSQL integration test fixtures.

Usage: DATABASE_URL_TEST=postgresql://theroad_test:test_pass@localhost:5433/theroad_test pytest tests/ -m pg

⚠️ 2026-04-27 hotfix: `from app.core.database import Base`를 module-level에서 하면
   tests/conftest.py가 환경변수를 설정하기 전에 settings/engine이 production 값으로
   캐시된다. `app` 관련 import는 모두 fixture 내부로 lazy 처리.
"""
import os

import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# conftest.py 가 ENVIRONMENT=test setup 시 DATABASE_URL 을 test PG 로 강제 set.
# 따라서 default 는 conftest.py 가 정한 DATABASE_URL 을 follow — 두 fixture set
# (default + pg_*) 가 동일 PG instance 사용. 별도 test PG instance (5433 등) 가
# 필요한 환경은 DATABASE_URL_TEST 로 override.
PG_URL = os.environ.get(
    "DATABASE_URL_TEST",
    os.environ.get(
        "DATABASE_URL",
        "postgresql://theroad:theroad_dev_2026@localhost:5432/theroad_test",
    ),
)


def _assert_test_pg_url(url: str) -> None:
    """PG_URL 이 production DB 를 가리키지 않도록 강제 (사고 회귀 가드).

    **db name allowlist**: 반드시 ``_test`` suffix 또는 ``:memory:``. 외부 env
    의 ``DATABASE_URL_TEST`` 가 production DSN 을 가리켜도 차단. ENVIRONMENT
    값 무관 — Codex P1 fix (이전 ``ENVIRONMENT == "test"`` 우회가 prod DSN
    누설 가능했던 케이스 회귀 가드).

    추가: ``_ORIGINAL_DATABASE_URL`` (conftest.py 가 보존한 덮어쓰기 전 prod URL)
    과 비교 — conftest 가 이미 test URL 로 덮어쓴 ``DATABASE_URL`` 보다 신뢰.
    """
    db_name = url.rstrip("/").split("/")[-1].split("?")[0]
    if not (db_name.endswith("_test") or db_name == ":memory:"):
        raise RuntimeError(
            f"REFUSING PG test target without '_test' suffix: db_name={db_name!r} "
            f"(url={url!r}). DATABASE_URL_TEST 는 반드시 별도 test DB ('_test' "
            f"접미사 필수) 를 가리켜야 한다."
        )
    original_prod_url = os.environ.get(
        "_ORIGINAL_DATABASE_URL",
        os.environ.get("DATABASE_URL", ""),
    )
    if original_prod_url and original_prod_url == url:
        raise RuntimeError(
            f"REFUSING to use production DATABASE_URL as PG test target: {url!r}. "
            f"Set DATABASE_URL_TEST to a dedicated test PG instance."
        )


@pytest.fixture(scope="session")
def pg_engine():
    # lazy import — env 설정(tests/conftest.py)이 끝난 후 평가되도록.
    from app.core.database import Base
    from tests._safety_guards import safe_drop_all
    # Codex P2 fix: 모델을 모두 import 해 metadata 에 등록.
    # 없으면 ``Base.metadata.create_all`` 이 빈 schema 만 생성하고
    # raw INSERT 들이 undefined-table 로 fail (단독 모듈 실행 시).
    import app.models.catalog  # noqa: F401
    import app.models.project  # noqa: F401
    from app.logging.models import ActivityLog  # noqa: F401  pylint: disable=unused-import

    _assert_test_pg_url(PG_URL)
    engine = create_engine(PG_URL, pool_pre_ping=True)
    Base.metadata.create_all(engine)
    yield engine
    # PR #5 hotfix Critical 1: raw drop_all 대신 safe_drop_all로 production DB
    # 보호 가드를 통과시킨다. PG_URL이 sanity 체크를 통과해도 fail-safe.
    safe_drop_all(engine, Base.metadata)


@pytest.fixture
def pg_session(pg_engine):
    Session = sessionmaker(bind=pg_engine)
    session = Session()
    yield session
    session.rollback()
    session.close()
