"""Configuration for GQLDB Python driver."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import List, Optional
import ssl


@dataclass
class GqldbConfig:
    """Configuration for connecting to GQLDB."""

    # Server hosts in format "host:port"
    hosts: List[str] = field(default_factory=lambda: ["localhost:9000"])

    # Authentication credentials
    username: str = ""
    password: str = ""

    # Default graph to use
    default_graph: str = ""

    # Query timeout in seconds
    timeout: int = 30

    # Maximum receive message size in bytes (default 64MB)
    max_recv_size: int = 64 * 1024 * 1024

    # TLS/SSL configuration
    ssl_context: Optional[ssl.SSLContext] = None

    # Connection pool size per host
    pool_size: int = 10

    # Health check interval in seconds
    health_check_interval: float = 30.0

    # Number of retries for failed requests
    retry_count: int = 3

    # Delay between retries in seconds
    retry_delay: float = 0.1

    def validate(self) -> None:
        """Validate the configuration.

        Raises:
            ValueError: If configuration is invalid.
        """
        if not self.hosts:
            raise ValueError("No hosts configured")

        if self.timeout < 0:
            raise ValueError("Invalid timeout value")

        if self.max_recv_size <= 0:
            self.max_recv_size = 64 * 1024 * 1024  # Default to 64MB

        if self.pool_size <= 0:
            self.pool_size = 10


class ConfigBuilder:
    """Builder for creating GqldbConfig."""

    def __init__(self) -> None:
        self._config = GqldbConfig()

    def hosts(self, *hosts: str) -> "ConfigBuilder":
        """Set the server hosts."""
        self._config.hosts = list(hosts)
        return self

    def username(self, username: str) -> "ConfigBuilder":
        """Set the username for authentication."""
        self._config.username = username
        return self

    def password(self, password: str) -> "ConfigBuilder":
        """Set the password for authentication."""
        self._config.password = password
        return self

    def default_graph(self, graph: str) -> "ConfigBuilder":
        """Set the default graph."""
        self._config.default_graph = graph
        return self

    def timeout(self, seconds: int) -> "ConfigBuilder":
        """Set the query timeout in seconds."""
        self._config.timeout = seconds
        return self

    def max_recv_size(self, bytes_: int) -> "ConfigBuilder":
        """Set the maximum receive message size."""
        self._config.max_recv_size = bytes_
        return self

    def ssl(self, ssl_context: ssl.SSLContext) -> "ConfigBuilder":
        """Set the SSL context."""
        self._config.ssl_context = ssl_context
        return self

    def pool_size(self, size: int) -> "ConfigBuilder":
        """Set the connection pool size per host."""
        self._config.pool_size = size
        return self

    def health_check_interval(self, seconds: float) -> "ConfigBuilder":
        """Set the health check interval."""
        self._config.health_check_interval = seconds
        return self

    def retry_count(self, count: int) -> "ConfigBuilder":
        """Set the number of retries."""
        self._config.retry_count = count
        return self

    def retry_delay(self, seconds: float) -> "ConfigBuilder":
        """Set the delay between retries."""
        self._config.retry_delay = seconds
        return self

    def build(self) -> GqldbConfig:
        """Build and return the configuration."""
        self._config.validate()
        return self._config


def create_ssl_context(
    cert_file: Optional[str] = None,
    key_file: Optional[str] = None,
    ca_file: Optional[str] = None,
    verify: bool = True,
) -> ssl.SSLContext:
    """Create an SSL context for secure connections.

    Args:
        cert_file: Path to client certificate file.
        key_file: Path to client key file.
        ca_file: Path to CA certificate file.
        verify: Whether to verify server certificates.

    Returns:
        Configured SSL context.
    """
    context = ssl.create_default_context()

    if not verify:
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
    elif ca_file:
        context.load_verify_locations(ca_file)

    if cert_file and key_file:
        context.load_cert_chain(cert_file, key_file)

    return context
