"""Tests for /api/sync/manifest — query_mode and source_type per table.

These tests target the `_build_manifest_for_user` helper directly so they can
exercise the query_mode/source_type joining logic without going through the
HTTP layer. The CLI (Task 7) relies on these fields to skip remote-mode
tables during download.
"""

import importlib


def _reload_db_module(monkeypatch, tmp_path):
    """Point DATA_DIR at tmp_path and reload db module so paths take effect."""
    monkeypatch.setenv("DATA_DIR", str(tmp_path))
    (tmp_path / "state").mkdir(exist_ok=True)
    import src.db as db_module
    importlib.reload(db_module)
    return db_module


def _ensure_admin1(conn):
    """Seed an admin user with id='admin1' + Admin group membership so
    {"id": "admin1", ...} dicts pass the can_access admin shortcut."""
    from src.db import SYSTEM_ADMIN_GROUP
    from src.repositories.users import UserRepository
    from src.repositories.user_group_members import UserGroupMembersRepository
    if UserRepository(conn).get_by_id("admin1") is None:
        UserRepository(conn).create(id="admin1", email="admin1@test.com", name="Admin")
    admin_gid = conn.execute(
        "SELECT id FROM user_groups WHERE name = ?", [SYSTEM_ADMIN_GROUP]
    ).fetchone()
    if admin_gid:
        UserGroupMembersRepository(conn).add_member(
            "admin1", admin_gid[0], source="system_seed",
        )


def test_manifest_includes_query_mode_for_local_table(tmp_path, monkeypatch):
    """Local-mode table must surface query_mode='local' in manifest."""
    db_module = _reload_db_module(monkeypatch, tmp_path)

    from src.repositories.sync_state import SyncStateRepository
    from src.repositories.table_registry import TableRegistryRepository
    from app.api.sync import _build_manifest_for_user

    conn = db_module.get_system_db()
    try:
        _ensure_admin1(conn)
        TableRegistryRepository(conn).register(
            id="orders", name="orders", source_type="keboola",
            bucket="sales", source_table="orders", query_mode="local",
        )
        SyncStateRepository(conn).update_sync(
            table_id="orders", rows=10, file_size_bytes=1024, hash="abc",
        )
        admin = {"id": "admin1", "email": "a@x.com"}
        manifest = _build_manifest_for_user(conn, admin)
        assert manifest["tables"]["orders"]["query_mode"] == "local"
        assert manifest["tables"]["orders"]["source_type"] == "keboola"
        assert manifest["tables"]["orders"]["hash"] == "abc"
        assert manifest["tables"]["orders"]["rows"] == 10
        assert manifest["tables"]["orders"]["size_bytes"] == 1024
    finally:
        conn.close()


def test_manifest_includes_query_mode_for_remote_table(tmp_path, monkeypatch):
    """Remote-mode table (BQ) must surface query_mode='remote' in manifest."""
    db_module = _reload_db_module(monkeypatch, tmp_path)

    from src.repositories.sync_state import SyncStateRepository
    from src.repositories.table_registry import TableRegistryRepository
    from app.api.sync import _build_manifest_for_user

    conn = db_module.get_system_db()
    try:
        _ensure_admin1(conn)
        TableRegistryRepository(conn).register(
            id="bq_view", name="bq_view", source_type="bigquery",
            bucket="ds", source_table="bq_view", query_mode="remote",
        )
        SyncStateRepository(conn).update_sync(
            table_id="bq_view", rows=0, file_size_bytes=0, hash="",
        )
        admin = {"id": "admin1", "email": "a@x.com"}
        manifest = _build_manifest_for_user(conn, admin)
        assert manifest["tables"]["bq_view"]["query_mode"] == "remote"
        assert manifest["tables"]["bq_view"]["source_type"] == "bigquery"
    finally:
        conn.close()


def test_manifest_defaults_query_mode_local_for_unregistered_state(tmp_path, monkeypatch):
    """Sync state without a corresponding registry row must default query_mode='local'.

    Defensive: if registry lookup misses (deleted entry, race), don't break the manifest.
    """
    db_module = _reload_db_module(monkeypatch, tmp_path)

    from src.repositories.sync_state import SyncStateRepository
    from app.api.sync import _build_manifest_for_user

    conn = db_module.get_system_db()
    try:
        _ensure_admin1(conn)
        SyncStateRepository(conn).update_sync(
            table_id="orphan", rows=0, file_size_bytes=0, hash="",
        )
        admin = {"id": "admin1", "email": "a@x.com"}
        manifest = _build_manifest_for_user(conn, admin)
        assert manifest["tables"]["orphan"]["query_mode"] == "local"
        assert manifest["tables"]["orphan"]["source_type"] == ""
    finally:
        conn.close()
