from collections.abc import Generator
from types import ModuleType
from unittest.mock import MagicMock

import pytest
from fastapi.testclient import TestClient
from src.client_api import app
from src.const import CLIENT_API_KEY_HEADER, CLIENT_IDEMPOTENCY_KEY_HEADER, CLIENT_TENANT_NAME_HEADER
from src.infrastructure import usage_event_request_queue, usage_event_request_storage
from src.infrastructure.clients.s3_client import S3Client
from src.infrastructure.clients.sqs_client import SqsClient


@pytest.fixture(scope="session")
def registered_identifiers() -> dict[str, str]:
    return {
        "api_key_gen_ai_profile": (
            "test.gen_ai_profile.test.46b7e57d4185a394eb5a90ea.m-sx73A01Z2wizMAvXeb9sWEHYv5VtOS-wLxVSbyTHg"
        ),
        "api_key_hci": ("test.hci.test.7e143149e80eb9d91e3c4e18.NDuDE5FeZVNOc9QYAmIS3jGiYnXd8omLnqWVxGWZoew"),
        "api_key_companyme": (
            "test.companyme.test.3768d4889929f6d39b7c55b8.8O-or31BwL_mibWIepmlq5-9V1ord9oW4V2o1qL7TR8"
        ),
        "tenant_alpha_1": "client_tenant_alpha_alpha_1",
        "tenant_alpha_2": "client_tenant_alpha_alpha_2",
        "tenant_beta_1": "client_tenant_beta_beta_1",
        "tenant_gen_ai_profile_1": "client_tenant_alpha_gen_ai_profile_1",
        "tenant_gen_ai_profile_2": "client_tenant_alpha_gen_ai_profile_2",
        "tenant_gen_ai_profile_3": "client_tenant_alpha_gen_ai_profile_3",
        "tenant_gen_ai_profile_4": "client_tenant_omega_gen_ai_profile_4",
        "tenant_hci_1": "client_tenant_alpha_hci_1",
        "tenant_hci_2": "client_tenant_gamma_hci_2",
        "service_gen_ai_profile": "gen_ai_profile",
        "feature_chat": "chat",
        "code_input_token": "test.testModel.inputToken",
        "sfdc_whi_alpha": "whi#alpha_1",
        "sfdc_whi_beta": "whi#beta",
    }


@pytest.fixture(scope="session")
def header_names() -> dict[str, str]:
    return {
        "api_key": CLIENT_API_KEY_HEADER,
        "tenant_name": CLIENT_TENANT_NAME_HEADER,
        "idempotency_key": CLIENT_IDEMPOTENCY_KEY_HEADER,
    }


@pytest.fixture
def target_router_module() -> ModuleType:
    msg = "target_router_module fixture must be defined by each integration test module."
    raise NotImplementedError(msg)


@pytest.fixture
def mock_s3_client(monkeypatch: pytest.MonkeyPatch, target_router_module: ModuleType) -> MagicMock:
    monkeypatch.setattr(
        target=usage_event_request_storage.settings,
        name="usage_event_storage_name",
        value="integration-test-bucket",
    )
    mock_s3_client_instance = MagicMock(spec_set=S3Client)
    mock_s3_client_factory = MagicMock(spec_set=S3Client, return_value=mock_s3_client_instance)
    monkeypatch.setattr(target=target_router_module, name="S3Client", value=mock_s3_client_factory)
    return mock_s3_client_instance


@pytest.fixture
def mock_sqs_client(monkeypatch: pytest.MonkeyPatch, target_router_module: ModuleType) -> MagicMock:
    monkeypatch.setattr(
        target=usage_event_request_queue.settings,
        name="usage_event_queue_url",
        value="https://sqs.ap-northeast-1.amazonaws.com/123456789012/integration-test-queue",
    )
    mock_sqs_client_instance = MagicMock(spec_set=SqsClient)
    mock_sqs_client_factory = MagicMock(spec_set=SqsClient, return_value=mock_sqs_client_instance)
    monkeypatch.setattr(target=target_router_module, name="SqsClient", value=mock_sqs_client_factory)
    return mock_sqs_client_instance


@pytest.fixture
def test_client() -> Generator[TestClient, None, None]:
    with TestClient(app) as test_client:
        yield test_client
