"""Proxy tests domain — sync and async mixins."""

from __future__ import annotations

from typing import Any

from ...exceptions import api_error_handler, async_api_error_handler
from ..._api.generated.proxies.proxies__api__proxies.models import (
    PaginatedProxyTestList,
    PatchedProxyTestRequest,
    ProxyTest,
    ProxyTestRequest,
)
from ._utils import coerce_test_type


class _TestsMixin:
    """Sync proxy test methods."""

    _api: Any

    @api_error_handler
    def list_tests(
        self,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedProxyTestList:
        """List proxy tests."""
        return self._api.tests_list(page=page, page_size=page_size, search=search, ordering=ordering)

    @api_error_handler
    def get_test(self, test_id: str) -> ProxyTest:
        """Get test details."""
        return self._api.tests_retrieve(test_id)

    @api_error_handler
    def create_test(
        self,
        *,
        proxy: str,
        test_url: str | None = None,
        test_type: str | None = None,
    ) -> ProxyTest:
        """Create and run a proxy test."""
        request = ProxyTestRequest(  # type: ignore[call-arg]
            proxy=proxy,
            test_url=test_url,
            test_type=coerce_test_type(test_type),
        )
        return self._api.tests_create(request)

    @api_error_handler
    def update_test(
        self,
        test_id: str,
        *,
        proxy: str | None = None,
        test_url: str | None = None,
        test_type: str | None = None,
    ) -> ProxyTest:
        """Partially update a proxy test record."""
        data = PatchedProxyTestRequest(
            proxy=proxy,
            test_url=test_url,
            test_type=coerce_test_type(test_type) if test_type is not None else None,
        )
        return self._api.tests_partial_update(test_id, data)

    @api_error_handler
    def delete_test(self, test_id: str) -> bool:
        """Delete a test record."""
        self._api.tests_destroy(test_id)
        return True


class _AsyncTestsMixin:
    """Async proxy test methods."""

    _api: Any

    @async_api_error_handler
    async def list_tests(
        self,
        *,
        page: int = 1,
        page_size: int = 20,
        search: str | None = None,
        ordering: str | None = None,
    ) -> PaginatedProxyTestList:
        """List proxy tests."""
        return await self._api.tests_list(page=page, page_size=page_size, search=search, ordering=ordering)

    @async_api_error_handler
    async def get_test(self, test_id: str) -> ProxyTest:
        """Get test details."""
        return await self._api.tests_retrieve(test_id)

    @async_api_error_handler
    async def create_test(
        self,
        *,
        proxy: str,
        test_url: str | None = None,
        test_type: str | None = None,
    ) -> ProxyTest:
        """Create and run a proxy test."""
        request = ProxyTestRequest(  # type: ignore[call-arg]
            proxy=proxy,
            test_url=test_url,
            test_type=coerce_test_type(test_type),
        )
        return await self._api.tests_create(request)

    @async_api_error_handler
    async def update_test(
        self,
        test_id: str,
        *,
        proxy: str | None = None,
        test_url: str | None = None,
        test_type: str | None = None,
    ) -> ProxyTest:
        """Partially update a proxy test record."""
        data = PatchedProxyTestRequest(
            proxy=proxy,
            test_url=test_url,
            test_type=coerce_test_type(test_type) if test_type is not None else None,
        )
        return await self._api.tests_partial_update(test_id, data)

    @async_api_error_handler
    async def delete_test(self, test_id: str) -> bool:
        """Delete a test record."""
        await self._api.tests_destroy(test_id)
        return True
