# coding: utf-8

"""
Unified VirshSandbox Client

This module provides a unified client wrapper for the virsh-sandbox SDK,
offering a cleaner interface with flattened parameters instead of request objects.

Example:
    from virsh_sandbox import VirshSandbox

    async with VirshSandbox(host="http://localhost:8080") as client:
        # Create a sandbox with simple parameters
        await client.sandbox.create_sandbox(source_vm_name="ubuntu-base")
        # Run a command
        await client.command.run_command(command="ls", args=["-la"])
"""

from typing import Any, Dict, List, Optional, Tuple, Union

from virsh_sandbox.api.access_api import AccessApi
from virsh_sandbox.api.ansible_api import AnsibleApi
from virsh_sandbox.api.audit_api import AuditApi
from virsh_sandbox.api.command_api import CommandApi
from virsh_sandbox.api.file_api import FileApi
from virsh_sandbox.api.health_api import HealthApi
from virsh_sandbox.api.human_api import HumanApi
from virsh_sandbox.api.plan_api import PlanApi
from virsh_sandbox.api.sandbox_api import SandboxApi
from virsh_sandbox.api.tmux_api import TmuxApi
from virsh_sandbox.api.vms_api import VMsApi
from virsh_sandbox.api_client import ApiClient
from virsh_sandbox.configuration import Configuration


class AccessOperations:
    """Wrapper for AccessApi with simplified method signatures."""

    def __init__(self, api: AccessApi):
        self._api = api


class AnsibleOperations:
    """Wrapper for AnsibleApi with simplified method signatures."""

    def __init__(self, api: AnsibleApi):
        self._api = api


class AuditOperations:
    """Wrapper for AuditApi with simplified method signatures."""

    def __init__(self, api: AuditApi):
        self._api = api


class CommandOperations:
    """Wrapper for CommandApi with simplified method signatures."""

    def __init__(self, api: CommandApi):
        self._api = api


class FileOperations:
    """Wrapper for FileApi with simplified method signatures."""

    def __init__(self, api: FileApi):
        self._api = api


class HealthOperations:
    """Wrapper for HealthApi with simplified method signatures."""

    def __init__(self, api: HealthApi):
        self._api = api


class HumanOperations:
    """Wrapper for HumanApi with simplified method signatures."""

    def __init__(self, api: HumanApi):
        self._api = api


class PlanOperations:
    """Wrapper for PlanApi with simplified method signatures."""

    def __init__(self, api: PlanApi):
        self._api = api


class SandboxOperations:
    """Wrapper for SandboxApi with simplified method signatures."""

    def __init__(self, api: SandboxApi):
        self._api = api


class TmuxOperations:
    """Wrapper for TmuxApi with simplified method signatures."""

    def __init__(self, api: TmuxApi):
        self._api = api


class VMsOperations:
    """Wrapper for VMsApi with simplified method signatures."""

    def __init__(self, api: VMsApi):
        self._api = api


class VirshSandbox:
    """Unified client for the virsh-sandbox API.

    This class provides a single entry point for all virsh-sandbox API operations,
    with support for separate hosts for the main API and tmux API.
    All methods use flattened parameters instead of request objects.

    Args:
        host: Base URL for the main virsh-sandbox API
        tmux_host: Base URL for the tmux API (defaults to host)
        api_key: Optional API key for authentication
        verify_ssl: Whether to verify SSL certificates

    Example:
        >>> from virsh_sandbox import VirshSandbox
        >>> async with VirshSandbox() as client:
        ...     await client.sandbox.create_sandbox(source_vm_name="base-vm")
    """

    def __init__(
        self,
        host: str = "http://localhost:8080",
        tmux_host: Optional[str] = None,
        api_key: Optional[str] = None,
        access_token: Optional[str] = None,
        username: Optional[str] = None,
        password: Optional[str] = None,
        verify_ssl: bool = True,
        ssl_ca_cert: Optional[str] = None,
        retries: Optional[int] = None,
    ) -> None:
        """Initialize the VirshSandbox client."""
        self._main_config = Configuration(
            host=host,
            api_key={"Authorization": api_key} if api_key else None,
            access_token=access_token,
            username=username,
            password=password,
            ssl_ca_cert=ssl_ca_cert,
            retries=retries,
        )
        self._main_config.verify_ssl = verify_ssl
        self._main_api_client = ApiClient(configuration=self._main_config)

        tmux_host = tmux_host or host
        if tmux_host != host:
            self._tmux_config = Configuration(
                host=tmux_host,
                api_key={"Authorization": api_key} if api_key else None,
                access_token=access_token,
                username=username,
                password=password,
                ssl_ca_cert=ssl_ca_cert,
                retries=retries,
            )
            self._tmux_config.verify_ssl = verify_ssl
            self._tmux_api_client = ApiClient(configuration=self._tmux_config)
        else:
            self._tmux_config = self._main_config
            self._tmux_api_client = self._main_api_client

        self._access: Optional[AccessOperations] = None
        self._ansible: Optional[AnsibleOperations] = None
        self._audit: Optional[AuditOperations] = None
        self._command: Optional[CommandOperations] = None
        self._file: Optional[FileOperations] = None
        self._health: Optional[HealthOperations] = None
        self._human: Optional[HumanOperations] = None
        self._plan: Optional[PlanOperations] = None
        self._sandbox: Optional[SandboxOperations] = None
        self._tmux: Optional[TmuxOperations] = None
        self._vms: Optional[VMsOperations] = None

    @property
    def access(self) -> AccessOperations:
        """Access AccessApi operations."""
        if self._access is None:
            api = AccessApi(api_client=self._main_api_client)
            self._access = AccessOperations(api)
        return self._access

    @property
    def ansible(self) -> AnsibleOperations:
        """Access AnsibleApi operations."""
        if self._ansible is None:
            api = AnsibleApi(api_client=self._main_api_client)
            self._ansible = AnsibleOperations(api)
        return self._ansible

    @property
    def audit(self) -> AuditOperations:
        """Access AuditApi operations."""
        if self._audit is None:
            api = AuditApi(api_client=self._tmux_api_client)
            self._audit = AuditOperations(api)
        return self._audit

    @property
    def command(self) -> CommandOperations:
        """Access CommandApi operations."""
        if self._command is None:
            api = CommandApi(api_client=self._tmux_api_client)
            self._command = CommandOperations(api)
        return self._command

    @property
    def file(self) -> FileOperations:
        """Access FileApi operations."""
        if self._file is None:
            api = FileApi(api_client=self._tmux_api_client)
            self._file = FileOperations(api)
        return self._file

    @property
    def health(self) -> HealthOperations:
        """Access HealthApi operations."""
        if self._health is None:
            api = HealthApi(api_client=self._tmux_api_client)
            self._health = HealthOperations(api)
        return self._health

    @property
    def human(self) -> HumanOperations:
        """Access HumanApi operations."""
        if self._human is None:
            api = HumanApi(api_client=self._tmux_api_client)
            self._human = HumanOperations(api)
        return self._human

    @property
    def plan(self) -> PlanOperations:
        """Access PlanApi operations."""
        if self._plan is None:
            api = PlanApi(api_client=self._tmux_api_client)
            self._plan = PlanOperations(api)
        return self._plan

    @property
    def sandbox(self) -> SandboxOperations:
        """Access SandboxApi operations."""
        if self._sandbox is None:
            api = SandboxApi(api_client=self._main_api_client)
            self._sandbox = SandboxOperations(api)
        return self._sandbox

    @property
    def tmux(self) -> TmuxOperations:
        """Access TmuxApi operations."""
        if self._tmux is None:
            api = TmuxApi(api_client=self._tmux_api_client)
            self._tmux = TmuxOperations(api)
        return self._tmux

    @property
    def vms(self) -> VMsOperations:
        """Access VMsApi operations."""
        if self._vms is None:
            api = VMsApi(api_client=self._main_api_client)
            self._vms = VMsOperations(api)
        return self._vms

    @property
    def configuration(self) -> Configuration:
        """Get the main API configuration."""
        return self._main_config

    @property
    def tmux_configuration(self) -> Configuration:
        """Get the tmux API configuration."""
        return self._tmux_config

    def set_debug(self, debug: bool) -> None:
        """Enable or disable debug mode."""
        self._main_config.debug = debug
        if self._tmux_config is not self._main_config:
            self._tmux_config.debug = debug

    async def close(self) -> None:
        """Close the API client connections."""
        if hasattr(self._main_api_client.rest_client, "close"):
            await self._main_api_client.rest_client.close()
        if self._tmux_api_client is not self._main_api_client:
            if hasattr(self._tmux_api_client.rest_client, "close"):
                await self._tmux_api_client.rest_client.close()

    async def __aenter__(self) -> "VirshSandbox":
        """Async context manager entry."""
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
        """Async context manager exit."""
        await self.close()
