# #region TestSupersetProfileLookup [TYPE Module] [C:3] [SEMANTICS tests, superset, profile, lookup, fallback, sorting]
# @RELATION BINDS_TO -> SrcRoot
# @BRIEF Verifies Superset profile lookup adapter payload normalization and fallback error precedence.
# @LAYER Domain
# [SECTION: IMPORTS]
import json
from pathlib import Path
import pytest
import sys
from typing import Any

backend_dir = str(Path(__file__).parent.parent.parent.parent.resolve())
if backend_dir not in sys.path:
    sys.path.insert(0, backend_dir)
from src.core.superset_profile_lookup import SupersetAccountLookupAdapter
from src.core.utils.network import AuthenticationError, SupersetAPIError


# [/SECTION]
# #region _RecordingNetworkClient [TYPE Class] [C:2]
# @RELATION BINDS_TO -> TestSupersetProfileLookup
# @BRIEF Records request payloads and returns scripted responses for deterministic adapter tests.
# @INVARIANT  Each request consumes one scripted response in call order and persists call metadata.
class _RecordingNetworkClient:
    # #region __init__ [TYPE Function]
    # @PURPOSE: Initializes scripted network responses.
    # @PRE  scripted_responses is ordered per expected request sequence.
    # @POST  Instance stores response script and captures subsequent request calls.
    def __init__(self, scripted_responses: list[Any]):
        self._scripted_responses = scripted_responses
        self.calls: list[dict[str, Any]] = []
    # #endregion __init__
    # #region request [TYPE Function]
    # @PURPOSE: Mimics APIClient.request while capturing call arguments.
    # @PRE  method and endpoint are provided.
    # @POST  Returns scripted response or raises scripted exception.
    def request(
        self,
        method: str,
        endpoint: str,
        params: dict[str, Any] | None = None,
        **kwargs,
    ) -> dict[str, Any]:
        self.calls.append(
            {
                "method": method,
                "endpoint": endpoint,
                "params": params or {},
            }
        )
        index = len(self.calls) - 1
        response = self._scripted_responses[index]
        if isinstance(response, Exception):
            raise response
        return response
    # #endregion request
# #endregion _RecordingNetworkClient
# #region test_get_users_page_sends_lowercase_order_direction [TYPE Function]
# @RELATION BINDS_TO -> TestSupersetProfileLookup
# @BRIEF Ensures adapter sends lowercase order_direction compatible with Superset rison schema.
# @PRE  Adapter is initialized with recording network client.
# @POST  First request query payload contains order_direction='asc' for asc sort.
def test_get_users_page_sends_lowercase_order_direction():
    client = _RecordingNetworkClient(
        scripted_responses=[{"result": [{"username": "admin"}], "count": 1}]
    )
    adapter = SupersetAccountLookupAdapter(
        network_client=client, environment_id="ss-dev"
    )
    adapter.get_users_page(
        search="admin",
        page_index=0,
        page_size=20,
        sort_column="username",
        sort_order="asc",
    )
    sent_query = json.loads(client.calls[0]["params"]["q"])
    assert sent_query["order_direction"] == "asc"
# #endregion test_get_users_page_sends_lowercase_order_direction
# #region test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error [TYPE Function]
# @RELATION BINDS_TO -> TestSupersetProfileLookup
# @BRIEF Ensures fallback auth error does not mask primary schema/query failure.
# @PRE  Primary endpoint fails with SupersetAPIError and fallback fails with AuthenticationError.
# @POST  Raised exception remains primary SupersetAPIError (non-auth) to preserve root cause.
def test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error():
    client = _RecordingNetworkClient(
        scripted_responses=[
            SupersetAPIError("API Error 400: bad rison schema"),
            AuthenticationError(),
        ]
    )
    adapter = SupersetAccountLookupAdapter(
        network_client=client, environment_id="ss-dev"
    )
    with pytest.raises(SupersetAPIError) as exc_info:
        adapter.get_users_page(sort_order="asc")
    assert "API Error 400" in str(exc_info.value)
    assert not isinstance(exc_info.value, AuthenticationError)
# #endregion test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error
# #region test_get_users_page_uses_fallback_endpoint_when_primary_fails [TYPE Function]
# @RELATION BINDS_TO -> TestSupersetProfileLookup
# @BRIEF Verifies adapter retries second users endpoint and succeeds when fallback is healthy.
# @PRE  Primary endpoint fails; fallback returns valid users payload.
# @POST  Result status is success and both endpoints were attempted in order.
def test_get_users_page_uses_fallback_endpoint_when_primary_fails():
    client = _RecordingNetworkClient(
        scripted_responses=[
            SupersetAPIError("Primary endpoint failed"),
            {"result": [{"username": "admin"}], "count": 1},
        ]
    )
    adapter = SupersetAccountLookupAdapter(
        network_client=client, environment_id="ss-dev"
    )
    result = adapter.get_users_page()
    assert result["status"] == "success"
    assert [call["endpoint"] for call in client.calls] == [
        "/security/users/",
        "/security/users",
    ]
# #endregion test_get_users_page_uses_fallback_endpoint_when_primary_fails
# #endregion TestSupersetProfileLookup
