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

from govcrawler import scheduler
from govcrawler.models import Base
from tests._v2fixtures import make_site, make_target


def test_spread_cron_default_lands_in_window():
    cron = scheduler.spread_cron("gdqy", "szfwj", scheduler.DEFAULT_SCHEDULE)
    minute, hour, *_ = cron.split()
    assert scheduler.WINDOW_START_HOUR <= int(hour) < scheduler.WINDOW_END_HOUR
    assert 0 <= int(minute) < 60


def test_spread_cron_custom_passthrough():
    custom = "15 9 * * MON-FRI"
    assert scheduler.spread_cron("x", "y", custom) == custom


def test_spread_cron_is_deterministic():
    a = scheduler.spread_cron("gdqy", "szfwj", scheduler.DEFAULT_SCHEDULE)
    b = scheduler.spread_cron("gdqy", "szfwj", scheduler.DEFAULT_SCHEDULE)
    assert a == b


def test_spread_cron_differs_across_columns():
    # At least some pair of (site, column) keys should land in different minutes
    crons = {
        scheduler.spread_cron("site_a", "col_a", scheduler.DEFAULT_SCHEDULE),
        scheduler.spread_cron("site_b", "col_b", scheduler.DEFAULT_SCHEDULE),
        scheduler.spread_cron("site_c", "col_c", scheduler.DEFAULT_SCHEDULE),
        scheduler.spread_cron("site_d", "col_d", scheduler.DEFAULT_SCHEDULE),
    }
    assert len(crons) >= 2   # not all collapsing to one cell


def test_build_scheduler_registers_one_job_per_column(monkeypatch):
    from govcrawler.config import registry
    registry.reload()

    calls: list[tuple[str, str]] = []
    sched = scheduler.build_scheduler(lambda s, c: calls.append((s, c)))
    jobs = sched.get_jobs()
    # gdqy has 1 enabled column (szfwj)
    assert any(j.id == "gdqy.szfwj" for j in jobs)
    # Job hasn't fired — calls empty
    assert calls == []
    # BlockingScheduler isn't started here, so no shutdown needed


def test_build_target_scheduler_registers_enabled_db_targets(tmp_path, monkeypatch):
    engine = create_engine("sqlite:///" + str(tmp_path / "sched.db"), future=True)
    Base.metadata.create_all(engine)
    SM = sessionmaker(bind=engine, expire_on_commit=False)
    monkeypatch.setattr(scheduler, "get_sessionmaker", lambda: SM)

    with SM() as s:
        site = make_site(s, site_code="demo", yaml_path="demo.yaml")
        make_target(s, site=site, column_id="c1", enabled=True)
        make_target(s, site=site, column_id="c2", enabled=False)
        disabled_site = make_site(s, site_code="off", yaml_path="off.yaml", enabled=False)
        make_target(s, site=disabled_site, column_id="c1", enabled=True)
        s.commit()

    calls: list[str] = []
    sched = scheduler.build_target_scheduler(lambda target: calls.append(target))
    job_ids = {j.id for j in sched.get_jobs()}
    assert "target.demo__c1" in job_ids
    assert "target.demo__c2" not in job_ids
    assert "target.off__c1" not in job_ids
    assert calls == []
