# ETCD Cluster Template
# Extracted from wuji infrastructure patterns (real production config)
# Provides ETCD configuration with SSL and clustering settings

import taskservs.networking.etcd.kcl.etcd as etcd
import workspace_templates.lib.compose as comp

# Base ETCD configuration schema from wuji production
schema ETCDBase {
    # Version configuration (production-tested from wuji)
    version: str = "3.5.14"

    # SSL configuration (production settings from wuji)
    ssl_mode: str = "openssl"    # cfssl or openssl
    ssl_sign: str = "ECC"        # ECC or RSA
    ca_sign: str = "ECC"         # ECC or RSA
    sign_sha: int = 384          # 256 or 384
    ssl_curve: str = "secp384r1" # For ECC

    # Cluster configuration
    cluster_name: str  # Must be provided
    hostname: str = "{{hostname}}"
    token: str = "etcd-server"

    # Certificate configuration
    c: str = "ES"                        # Country
    cn: str = "librecloud.online"        # Common name
    sign_pass: str = "cloudMeFree"       # Certificate signing password

    # Network configuration
    cli_ip: str = "{{network_private_ip}}"
    peer_ip: str = "{{network_private_ip}}"
    cli_port: int = 2379
    peer_port: int = 2380

    # Cluster members
    cluster_list: str = ""  # Comma-separated list of cluster members

    # Paths and directories
    data_dir: str = "/var/lib/etcd"
    conf_path: str = "/etc/etcd/config.yaml"
    certs_path: str = "/etc/ssl/etcd"
    prov_path: str = "etcdcerts"

    # Logging configuration
    log_level: str = "warn"
    log_out: str = "stderr"

    # Listen and advertise configurations (templated)
    listen_peers: str = "{{servers}}:{{network_private_ip}}:{{peer_port}}"
    listen_clients: str = "{{servers}}:{{network_private_ip}}:{{cli_port}}"
    adv_listen_peers: str = "{{servers}}:{{network_private_ip}}:{{peer_port}}"
    adv_listen_clients: str = "{{servers}}:{{network_private_ip}}:{{cli_port}}"
    initial_peers: str = "{{servers}}:{{network_private_ip}}:{{peer_port}}"

    # Domain and DNS configuration
    domain_name: str = "{{defaults}}"
    use_dns: bool = True
    discovery_srv: str = ""

    # Additional configuration
    custom_config: {str: any} = {}
}

# Template function to create ETCD configuration
def create_etcd_base [
    cluster_name: str,
    domain: str = "librecloud.online",
    cluster_members: [str] = [],
    overrides: {str: any} = {}
] -> any {
    let base_config = ETCDBase {
        cluster_name: $cluster_name
        cn: $domain
        cluster_list: ($cluster_members | str join ",")
    }

    # Apply overrides
    let final_config = comp.deep_merge $base_config $overrides

    # Create core ETCD configuration
    etcd.ETCD {
        version: $final_config.version
        ssl_mode: $final_config.ssl_mode
        ssl_sign: $final_config.ssl_sign
        ca_sign: $final_config.ca_sign
        sign_sha: $final_config.sign_sha
        ssl_curve: $final_config.ssl_curve
        cluster_name: $final_config.cluster_name
        hostname: $final_config.hostname
        c: $final_config.c
        cn: $final_config.cn
        cli_ip: $final_config.cli_ip
        peer_ip: $final_config.peer_ip
        cli_port: $final_config.cli_port
        peer_port: $final_config.peer_port
        cluster_list: $final_config.cluster_list
        token: $final_config.token
        sign_pass: $final_config.sign_pass
        data_dir: $final_config.data_dir
        conf_path: $final_config.conf_path
        log_level: $final_config.log_level
        log_out: $final_config.log_out
        certs_path: $final_config.certs_path
        prov_path: $final_config.prov_path
        listen_peers: $final_config.listen_peers
        listen_clients: $final_config.listen_clients
        adv_listen_peers: $final_config.adv_listen_peers
        adv_listen_clients: $final_config.adv_listen_clients
        initial_peers: $final_config.initial_peers
        domain_name: $final_config.domain_name
        use_dns: $final_config.use_dns
        discovery_srv: $final_config.discovery_srv
    } | comp.deep_merge $final_config.custom_config
}

# SSL configuration presets
ssl_configs = {
    # High security (ECC 384-bit)
    high_security: {
        ssl_sign: "ECC"
        ca_sign: "ECC"
        sign_sha: 384
        ssl_curve: "secp384r1"
    }
    # Standard security (ECC 256-bit)
    standard: {
        ssl_sign: "ECC"
        ca_sign: "ECC"
        sign_sha: 256
        ssl_curve: "secp256r1"
    }
    # RSA compatibility
    rsa: {
        ssl_sign: "RSA"
        ca_sign: "RSA"
        sign_sha: 256
        ssl_curve: ""
    }
}

# Export the template schema
_etcd_taskserv = etcd.ETCD {
    version = "3.5.14"
    ssl_mode = "openssl"
    ssl_sign = "ECC"
    ca_sign = "ECC"
    sign_sha = 384
    ssl_curve = "secp384r1"
    cluster_name = "etcd-cluster"
    hostname = "{{hostname}}"
    token = "etcd-server"
    c = "ES"
    cn = "librecloud.online"
    sign_pass = "cloudMeFree"
    cli_ip = "{{network_private_ip}}"
    peer_ip = "{{network_private_ip}}"
    cli_port = 2379
    peer_port = 2380
    cluster_list = ""
    data_dir = "/var/lib/etcd"
    conf_path = "/etc/etcd/config.yaml"
    certs_path = "/etc/ssl/etcd"
    prov_path = "etcdcerts"
    log_level = "warn"
    log_out = "stderr"
    listen_peers = "{{servers}}:{{network_private_ip}}:{{peer_port}}"
    listen_clients = "{{servers}}:{{network_private_ip}}:{{cli_port}}"
    adv_listen_peers = "{{servers}}:{{network_private_ip}}:{{peer_port}}"
    adv_listen_clients = "{{servers}}:{{network_private_ip}}:{{cli_port}}"
    initial_peers = "{{servers}}:{{network_private_ip}}:{{peer_port}}"
    domain_name = "{{defaults}}"
    use_dns = True
    discovery_srv = ""
}

_etcd_taskserv
