"""TableRegistryRepository.register() persists v27 sync-strategy columns.

where_filters is JSON-encoded on write, decoded on read (matching the
pattern used for primary_key). Other fields are scalar pass-through.
"""
import duckdb
import pytest

from src.db import _V26_TO_V27_MIGRATIONS
from src.repositories.table_registry import TableRegistryRepository


@pytest.fixture
def repo(tmp_path):
    conn = duckdb.connect(str(tmp_path / "test.duckdb"))
    # Match the post-v26 shape that v27 migrations alter (main's v26 is a
    # data migration with no schema change so the column shape is unchanged
    # from v25; we only need to seed the canonical post-v25 column set).
    conn.execute(
        "CREATE TABLE table_registry ("
        "id VARCHAR PRIMARY KEY, name VARCHAR NOT NULL, folder VARCHAR, "
        "sync_strategy VARCHAR DEFAULT 'full_refresh', primary_key VARCHAR, "
        "description TEXT, registered_by VARCHAR, "
        "registered_at TIMESTAMP DEFAULT current_timestamp, "
        "source_type VARCHAR, bucket VARCHAR, source_table VARCHAR, "
        "source_query TEXT, query_mode VARCHAR DEFAULT 'local', "
        "sync_schedule VARCHAR, profile_after_sync BOOLEAN DEFAULT true)"
    )
    for sql in _V26_TO_V27_MIGRATIONS:
        conn.execute(sql)
    return TableRegistryRepository(conn)


def test_register_with_incremental_fields(repo):
    repo.register(
        id="in.c-crm.activity",
        name="activity",
        source_type="keboola",
        bucket="in.c-crm",
        source_table="activity",
        sync_strategy="incremental",
        primary_key=["activity_id"],
        incremental_window_days=1,
        max_history_days=180,
    )
    got = repo.get("in.c-crm.activity")
    assert got["sync_strategy"] == "incremental"
    assert got["incremental_window_days"] == 1
    assert got["max_history_days"] == 180
    assert got["incremental_column"] is None
    assert got["where_filters"] is None


def test_register_with_partitioned_fields(repo):
    repo.register(
        id="in.c-sales.orders",
        name="orders",
        source_type="keboola",
        bucket="in.c-sales",
        source_table="orders",
        sync_strategy="partitioned",
        primary_key=["id"],
        partition_by="date",
        partition_granularity="month",
        initial_load_chunk_days=30,
    )
    got = repo.get("in.c-sales.orders")
    assert got["partition_by"] == "date"
    assert got["partition_granularity"] == "month"
    assert got["initial_load_chunk_days"] == 30


def test_register_with_where_filters_encodes_json(repo):
    filters = [
        {"column": "date", "operator": "ge", "values": ["{{last_3_months}}"]},
        {"column": "country_code", "operator": "eq", "values": ["CZ", "SK"]},
    ]
    repo.register(
        id="in.c-x.y",
        name="y",
        source_type="keboola",
        bucket="in.c-x",
        source_table="y",
        where_filters=filters,
    )
    got = repo.get("in.c-x.y")
    assert got["where_filters"] == filters


def test_register_no_optional_fields_leaves_them_null(repo):
    repo.register(
        id="in.c-crm.company",
        name="company",
        source_type="keboola",
        bucket="in.c-crm",
        source_table="company",
    )
    got = repo.get("in.c-crm.company")
    assert got["sync_strategy"] == "full_refresh"
    assert got["incremental_window_days"] is None
    assert got["where_filters"] is None
    assert got["partition_by"] is None


def test_register_upsert_overwrites_v26_fields(repo):
    repo.register(
        id="in.c-crm.activity", name="activity",
        source_type="keboola", bucket="in.c-crm", source_table="activity",
        sync_strategy="incremental", incremental_window_days=1,
    )
    repo.register(
        id="in.c-crm.activity", name="activity",
        source_type="keboola", bucket="in.c-crm", source_table="activity",
        sync_strategy="incremental", incremental_window_days=7,
        max_history_days=90,
    )
    got = repo.get("in.c-crm.activity")
    assert got["incremental_window_days"] == 7
    assert got["max_history_days"] == 90
