"""Connector field-definition completeness and required-field enforcement."""
from __future__ import annotations

import pytest
from src.core.exceptions import ValidationError
from src.domain.connectors.catalog import CONNECTORS, get_connector
from src.domain.connectors.service import _validate_required_connector_fields


def test_every_connector_field_def_set_matches_its_field_tuple() -> None:
    """If any field_defs are declared, they must cover every field in the tuple —
    the dashboard renders config_field_defs/secret_field_defs as-is when present,
    with no per-field fallback for keys missing a def."""
    for cdef in CONNECTORS.values():
        config_def_keys = {f.key for f in cdef.config_field_defs}
        if config_def_keys:
            assert config_def_keys == set(cdef.config_fields), cdef.key

        secret_def_keys = {f.key for f in cdef.secret_field_defs}
        if secret_def_keys:
            assert secret_def_keys == set(cdef.secret_fields), cdef.key


@pytest.mark.parametrize("key", ["n8n", "make_com", "slack", "twilio", "paypal", "calendly", "google_calendar", "google_docs"])
def test_new_connectors_are_registered(key: str) -> None:
    assert get_connector(key) is not None


def test_missing_required_secret_rejected_on_create() -> None:
    stripe = get_connector("stripe")
    with pytest.raises(ValidationError, match="secret_key"):
        _validate_required_connector_fields(stripe, {}, {}, require_all_secrets=True)


def test_partial_update_does_not_require_resupplying_secrets() -> None:
    stripe = get_connector("stripe")
    _validate_required_connector_fields(stripe, {}, {})  # should not raise


def test_blanking_a_required_secret_on_update_is_rejected() -> None:
    stripe = get_connector("stripe")
    with pytest.raises(ValidationError, match="cannot be empty"):
        _validate_required_connector_fields(stripe, {}, {"secret_key": "   "})


def test_missing_required_config_field_rejected() -> None:
    r2 = get_connector("cloudflare_r2")
    with pytest.raises(ValidationError, match="account_id"):
        _validate_required_connector_fields(r2, {}, {}, require_all_secrets=True)


def test_salesforce_requires_the_full_oauth_refresh_triple() -> None:
    salesforce = get_connector("salesforce")
    with pytest.raises(ValidationError, match="client_secret"):
        _validate_required_connector_fields(
            salesforce,
            {"instance_url": "https://x.my.salesforce.com", "client_id": "abc"},
            {"access_token": "a", "refresh_token": "b"},
            require_all_secrets=True,
        )


def test_complete_connector_passes_validation() -> None:
    salesforce = get_connector("salesforce")
    _validate_required_connector_fields(
        salesforce,
        {"instance_url": "https://x.my.salesforce.com", "client_id": "abc"},
        {"access_token": "a", "refresh_token": "b", "client_secret": "c"},
        require_all_secrets=True,
    )  # should not raise
