"""
Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com

Simple configuration generator for MCP Proxy Adapter.
"""

from __future__ import annotations

from typing import Optional

from .simple_config import (
    SimpleConfig,
    SimpleConfigModel,
    ServerConfig,
    ClientConfig,
    RegistrationConfig,
    HeartbeatConfig,
    AuthConfig,
    SSLConfig,
)


class SimpleConfigGenerator:
    """Generate minimal configuration according to the plan."""

    def generate(
        self,
        protocol: str,
        with_proxy: bool = False,
        out_path: str = "config.json",
        # Server parameters
        server_host: Optional[str] = None,
        server_port: Optional[int] = None,
        server_cert_file: Optional[str] = None,
        server_key_file: Optional[str] = None,
        server_ca_cert_file: Optional[str] = None,
        server_crl_file: Optional[str] = None,
        server_debug: Optional[bool] = None,
        server_log_level: Optional[str] = None,
        server_log_dir: Optional[str] = None,
        # Client parameters
        client_enabled: bool = False,
        client_protocol: Optional[str] = None,
        client_cert_file: Optional[str] = None,
        client_key_file: Optional[str] = None,
        client_ca_cert_file: Optional[str] = None,
        client_crl_file: Optional[str] = None,
        # Registration parameters
        registration_host: Optional[str] = None,
        registration_port: Optional[int] = None,
        registration_protocol: Optional[str] = None,
        registration_cert_file: Optional[str] = None,
        registration_key_file: Optional[str] = None,
        registration_ca_cert_file: Optional[str] = None,
        registration_crl_file: Optional[str] = None,
        registration_server_id: Optional[str] = None,
        registration_server_name: Optional[str] = None,
    ) -> str:
        """
        Generate configuration with optional custom parameters.
        
        Args:
            protocol: Server protocol (http, https, mtls)
            with_proxy: Enable proxy registration (deprecated, use registration parameters)
            out_path: Output file path
            # Server parameters
            server_host: Server host (default: 0.0.0.0)
            server_port: Server port (default: 8080)
            server_cert_file: Server certificate file path
            server_key_file: Server key file path
            server_ca_cert_file: Server CA certificate file path
            server_crl_file: Server CRL file path
            server_debug: Enable debug mode (default: False)
            server_log_level: Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL (default: INFO)
            server_log_dir: Log directory path (default: ./logs)
            # Client parameters
            client_enabled: Enable client configuration
            client_protocol: Client protocol (http, https, mtls)
            client_cert_file: Client certificate file path
            client_key_file: Client key file path
            client_ca_cert_file: Client CA certificate file path
            client_crl_file: Client CRL file path
            # Registration parameters
            registration_host: Registration proxy host (default: localhost)
            registration_port: Registration proxy port (default: 3005)
            registration_protocol: Registration protocol (http, https, mtls)
            registration_cert_file: Registration certificate file path
            registration_key_file: Registration key file path
            registration_ca_cert_file: Registration CA certificate file path
            registration_crl_file: Registration CRL file path
            registration_server_id: Server ID for registration
            registration_server_name: Server name for registration
        """
        # Server configuration with new structure
        server_host_val = server_host or "0.0.0.0"
        server_servername = server_host_val if server_host_val != "0.0.0.0" else "localhost"
        
        # Create SSL config if needed
        server_ssl = None
        if protocol in ("https", "mtls"):
            server_ssl = SSLConfig(
                cert=server_cert_file or "./certs/server.crt",
                key=server_key_file or "./certs/server.key",
                ca=server_ca_cert_file,
                crl=server_crl_file,
                dnscheck=False,  # Default false for server
            )
        
        server = ServerConfig(
            host=server_host_val,
            port=server_port or 8080,
            protocol=protocol,
            servername=server_servername,
            ssl=server_ssl,
            debug=server_debug if server_debug is not None else False,  # Default: production mode
            log_level=server_log_level or "INFO",  # Default: INFO level
            log_dir=server_log_dir or "./logs",  # Default: ./logs
        )

        # Client configuration
        client = ClientConfig(enabled=client_enabled)
        if client_enabled:
            client.protocol = client_protocol or protocol
            if client.protocol in ("https", "mtls"):
                client_ssl = SSLConfig(
                    cert=client_cert_file or "./certs/client.crt",
                    key=client_key_file or "./certs/client.key",
                    ca=client_ca_cert_file or ("./certs/ca.crt" if client.protocol == "mtls" else None),
                    crl=client_crl_file,
                    dnscheck=False,
                )
                client.ssl = client_ssl

        # Registration configuration
        if with_proxy:
            reg_host = registration_host or "localhost"
            reg_port = registration_port or 3005
            reg_protocol = registration_protocol or "http"
            
            # Determine URL scheme based on protocol
            scheme = "https" if reg_protocol in ("https", "mtls") else "http"
            
            # Create full URLs for registration and heartbeat
            register_url = f"{scheme}://{reg_host}:{reg_port}/register"
            unregister_url = f"{scheme}://{reg_host}:{reg_port}/unregister"
            heartbeat_url = f"{scheme}://{reg_host}:{reg_port}/proxy/heartbeat"
            
            # Create heartbeat config
            heartbeat_interval = 30
            heartbeat = HeartbeatConfig(url=heartbeat_url, interval=heartbeat_interval)
            
            # Create SSL config for registration if needed
            registration_ssl = None
            if reg_protocol in ("https", "mtls"):
                registration_ssl = SSLConfig(
                    cert=registration_cert_file or "./certs/registration.crt",
                    key=registration_key_file or "./certs/registration.key",
                    ca=registration_ca_cert_file or ("./certs/ca.crt" if reg_protocol == "mtls" else None),
                    crl=registration_crl_file,
                    dnscheck=True,  # Default true for registration
                )
            
            # Create registration config with new format
            registration = RegistrationConfig(
                enabled=True,
                protocol=reg_protocol,
                register_url=register_url,
                unregister_url=unregister_url,
                heartbeat_interval=heartbeat_interval,
                ssl=registration_ssl,
                heartbeat=heartbeat,
                auto_on_startup=True,
                server_id=registration_server_id,
                server_name=registration_server_name,
            )
        else:
            # Registration disabled - create minimal config with default URLs (not used when disabled)
            registration = RegistrationConfig(
                enabled=False,
                protocol="http",
                register_url="http://localhost:3005/register",  # Default value, not used when disabled
                heartbeat_interval=30,  # Required field even when disabled
                heartbeat=HeartbeatConfig(url="http://localhost:3005/proxy/heartbeat", interval=30),
            )

        auth = AuthConfig(use_token=False, use_roles=False, tokens={}, roles={})

        cfg = SimpleConfig()
        cfg.model = SimpleConfigModel(server=server, client=client, registration=registration, auth=auth)
        cfg.save(out_path)
        return out_path
