"""Read-only checks against the platform's real integration tables.

These tables belong to the Node application. The tests below read them and write
only rows scoped to the known test tenant, which is cleaned up afterwards.
"""
import pytest

from app.services.infra.database import get_master_db_connection
from app.services.integrations.platform import (
    TenantHasNoUserError, get_platform_config, resolve_tenant_user,
    strip_tenant_prefix, upsert_integration,
)

TENANT = "org_8c32bf3e-6a18-4739-9b1c-94c0cf11125f"
TENANT_UUID = "8c32bf3e-6a18-4739-9b1c-94c0cf11125f"


@pytest.fixture
def clean_integration():
    yield
    conn = get_master_db_connection()
    try:
        with conn.cursor() as cur:
            cur.execute('DELETE FROM integrations WHERE "tenantId" = %s '
                        "AND provider = 'shopify'", (TENANT_UUID,))
        conn.commit()
    finally:
        conn.close()


def test_the_test_tenant_has_an_owning_user():
    assert resolve_tenant_user(TENANT_UUID) is not None


def test_a_tenant_without_a_user_is_reported_not_crashed(clean_integration):
    # Two of 28 tenants have a null userId. integrations.user is NOT NULL, so
    # this must surface as a clear error rather than a constraint violation.
    conn = get_master_db_connection()
    try:
        with conn.cursor() as cur:
            cur.execute('SELECT id FROM "Tenants" WHERE "userId" IS NULL LIMIT 1')
            row = cur.fetchone()
    finally:
        conn.close()
    if not row:
        pytest.skip("no userless tenant in this database")

    with pytest.raises(TenantHasNoUserError):
        upsert_integration(f"org_{row[0]}", "shopify", "oauth2", "gAAAA", {})


def test_upsert_creates_then_updates_one_row(clean_integration):
    first = upsert_integration(TENANT, "shopify", "oauth2", "gAAAAciphertext1",
                               {"shop_domain": "a.myshopify.com"})
    second = upsert_integration(TENANT, "shopify", "oauth2", "gAAAAciphertext2",
                                {"shop_domain": "a.myshopify.com"})
    assert first == second

    conn = get_master_db_connection()
    try:
        with conn.cursor() as cur:
            cur.execute('SELECT count(*), max("accessToken"), max(metadata->>%s) '
                        'FROM integrations WHERE "tenantId" = %s AND provider = %s',
                        ("token_encoding", TENANT_UUID, "shopify"))
            count, token, encoding = cur.fetchone()
    finally:
        conn.close()

    assert count == 1
    assert token == "gAAAAciphertext2"
    assert encoding == "fernet"


def test_shopify_platform_config_is_absent_or_complete():
    # Task 4 adds this row. Before that it is absent, and the code must cope.
    # Cache cleared first so this reads the real row rather than a value
    # cached by an earlier test in the same process.
    import app.services.integrations.platform as mod
    mod._config_cache.clear()
    cfg = get_platform_config("shopify")
    if cfg is not None:
        assert cfg["client_id"]
        assert cfg["client_secret"]


def test_strip_prefix_matches_a_real_tenant_row():
    assert strip_tenant_prefix(TENANT) == TENANT_UUID
