"""Main EvalHub clients that combine all client capabilities."""

from __future__ import annotations

from functools import cached_property
from pathlib import Path

from .base import BaseAsyncClient, BaseSyncClient
from .resources import (
    AsyncBenchmarksResource,
    AsyncCollectionsResource,
    AsyncJobsResource,
    AsyncProvidersResource,
    SyncBenchmarksResource,
    SyncCollectionsResource,
    SyncJobsResource,
    SyncProvidersResource,
)


class AsyncEvalHubClient(BaseAsyncClient):
    """Complete asynchronous EvalHub client with all capabilities.

    This client provides access to all EvalHub API endpoints through a nested
    resource structure.

    All methods are async and must be awaited.

    Example:
        >>> async with AsyncEvalHubClient() as client:
        ...     providers = await client.providers.list()
        ...     benchmarks = await client.benchmarks.list()
        ...     job = await client.jobs.submit(request)
        ...     status = await client.jobs.get(job.id)
    """

    def __init__(
        self,
        base_url: str = "http://localhost:8080",
        auth_token: str | None = None,
        auth_token_path: Path | str | None = None,
        ca_bundle_path: Path | str | None = None,
        insecure: bool = False,
        timeout: float = 30.0,
        max_retries: int = 3,
        verify_ssl: bool = True,
        retry_initial_delay: float = 1.0,
        retry_max_delay: float = 60.0,
        retry_backoff_factor: float = 2.0,
        retry_randomization: bool = True,
    ):
        """Initialize the async EvalHub client.

        Args:
            base_url: Base URL of the EvalHub service (default: http://localhost:8080)
            auth_token: Explicit authentication token (overrides auto-detection)
            auth_token_path: Path to authentication token file (e.g., ServiceAccount token)
            ca_bundle_path: Path to CA bundle for TLS verification
            insecure: Allow insecure connections (skip TLS verification)
            timeout: Request timeout in seconds (default: 30.0)
            max_retries: Maximum number of retry attempts (default: 3)
            verify_ssl: Whether to verify SSL certificates (deprecated, use insecure instead)
            retry_initial_delay: Initial delay between retries in seconds (default: 1.0)
            retry_max_delay: Maximum delay between retries in seconds (default: 60.0)
            retry_backoff_factor: Multiplier for exponential backoff (default: 2.0)
            retry_randomization: Add random jitter to retry delays (default: True)
        """
        super().__init__(
            base_url=base_url,
            auth_token=auth_token,
            auth_token_path=auth_token_path,
            ca_bundle_path=ca_bundle_path,
            insecure=insecure,
            timeout=timeout,
            max_retries=max_retries,
            verify_ssl=verify_ssl,
            retry_initial_delay=retry_initial_delay,
            retry_max_delay=retry_max_delay,
            retry_backoff_factor=retry_backoff_factor,
            retry_randomization=retry_randomization,
        )

    @cached_property
    def providers(self) -> AsyncProvidersResource:
        """Access provider operations."""
        return AsyncProvidersResource(self)

    @cached_property
    def benchmarks(self) -> AsyncBenchmarksResource:
        """Access benchmark operations."""
        return AsyncBenchmarksResource(self)

    @cached_property
    def collections(self) -> AsyncCollectionsResource:
        """Access collection operations."""
        return AsyncCollectionsResource(self)

    @cached_property
    def jobs(self) -> AsyncJobsResource:
        """Access evaluation job operations."""
        return AsyncJobsResource(self)


class SyncEvalHubClient(BaseSyncClient):
    """Complete synchronous EvalHub client with all capabilities.

    This client provides access to all EvalHub API endpoints through a nested
    resource structure.

    All methods are synchronous and do not require await.

    Example:
        >>> with SyncEvalHubClient() as client:
        ...     providers = client.providers.list()
        ...     benchmarks = client.benchmarks.list()
        ...     job = client.jobs.submit(request)
        ...     status = client.jobs.get(job.id)
    """

    def __init__(
        self,
        base_url: str = "http://localhost:8080",
        auth_token: str | None = None,
        auth_token_path: Path | str | None = None,
        ca_bundle_path: Path | str | None = None,
        insecure: bool = False,
        timeout: float = 30.0,
        max_retries: int = 3,
        verify_ssl: bool = True,
        retry_initial_delay: float = 1.0,
        retry_max_delay: float = 60.0,
        retry_backoff_factor: float = 2.0,
        retry_randomization: bool = True,
    ):
        """Initialize the sync EvalHub client.

        Args:
            base_url: Base URL of the EvalHub service (default: http://localhost:8080)
            auth_token: Explicit authentication token (overrides auto-detection)
            auth_token_path: Path to authentication token file (e.g., ServiceAccount token)
            ca_bundle_path: Path to CA bundle for TLS verification
            insecure: Allow insecure connections (skip TLS verification)
            timeout: Request timeout in seconds (default: 30.0)
            max_retries: Maximum number of retry attempts (default: 3)
            verify_ssl: Whether to verify SSL certificates (deprecated, use insecure instead)
            retry_initial_delay: Initial delay between retries in seconds (default: 1.0)
            retry_max_delay: Maximum delay between retries in seconds (default: 60.0)
            retry_backoff_factor: Multiplier for exponential backoff (default: 2.0)
            retry_randomization: Add random jitter to retry delays (default: True)
        """
        super().__init__(
            base_url=base_url,
            auth_token=auth_token,
            auth_token_path=auth_token_path,
            ca_bundle_path=ca_bundle_path,
            insecure=insecure,
            timeout=timeout,
            max_retries=max_retries,
            verify_ssl=verify_ssl,
            retry_initial_delay=retry_initial_delay,
            retry_max_delay=retry_max_delay,
            retry_backoff_factor=retry_backoff_factor,
            retry_randomization=retry_randomization,
        )

    @cached_property
    def providers(self) -> SyncProvidersResource:
        """Access provider operations."""
        return SyncProvidersResource(self)

    @cached_property
    def benchmarks(self) -> SyncBenchmarksResource:
        """Access benchmark operations."""
        return SyncBenchmarksResource(self)

    @cached_property
    def collections(self) -> SyncCollectionsResource:
        """Access collection operations."""
        return SyncCollectionsResource(self)

    @cached_property
    def jobs(self) -> SyncJobsResource:
        """Access evaluation job operations."""
        return SyncJobsResource(self)


# Aliases for backward compatibility and convenience
EvalHubClient = AsyncEvalHubClient  # Default to async
