"""Shared test helpers for v2 schema.

Creates minimal crawl_site + crawl_target rows so legacy tests that used to
build Article/CrawlLog with string site_id/column_id can keep their
intent while using int FKs.
"""
from __future__ import annotations

from sqlalchemy.orm import Session

from govcrawler.models import CrawlSite, CrawlTarget


def make_site(
    s: Session,
    *,
    site_code: str = "demo",
    site_name: str = "演示站",
    base_url: str = "https://demo.example.com",
    cms_adapter: str | None = None,
    yaml_path: str | None = "demo.yaml",
    enabled: bool = True,
) -> CrawlSite:
    """Insert and flush a crawl_site row — XOR constraint requires exactly one
    of cms_adapter/yaml_path to be set."""
    # Enforce XOR client-side for a nicer error than CHECK constraint
    if (cms_adapter is None) == (yaml_path is None):
        raise ValueError("exactly one of cms_adapter / yaml_path must be set")
    row = CrawlSite(
        site_code=site_code,
        site_name=site_name,
        base_url=base_url,
        cms_adapter=cms_adapter,
        yaml_path=yaml_path,
        enabled=enabled,
        respect_robots=True,
    )
    s.add(row)
    s.flush()
    return row


def make_target(
    s: Session,
    *,
    site: CrawlSite,
    target_code: str | None = None,
    column_id: str = "c1",
    dept_path: str | None = None,
    target_name: str = "栏目一",
    entry_url: str = "https://demo.example.com/a/",
    enabled: bool = True,
) -> CrawlTarget:
    """Insert a crawl_target row. Derives target_code the same way yaml-sync does."""
    if target_code is None:
        target_code = (
            f"{site.site_code}__{dept_path}__{column_id}"
            if dept_path
            else f"{site.site_code}__{column_id}"
        )
    row = CrawlTarget(
        site_id=site.id,
        target_code=target_code,
        target_name=target_name,
        entry_url=entry_url,
        enabled=enabled,
    )
    s.add(row)
    s.flush()
    return row


def make_site_and_target(s: Session, **kwargs) -> tuple[CrawlSite, CrawlTarget]:
    """One-line convenience for tests that just need a pair."""
    site_code = kwargs.pop("site_code", "demo")
    column_id = kwargs.pop("column_id", "c1")
    site = make_site(s, site_code=site_code)
    target = make_target(s, site=site, column_id=column_id, **kwargs)
    return site, target
