# Info: KCL Coder task schemas for provisioning (Provisioning)
# Author: Provisioning System
# Release: 0.0.1
# Date: 2025-07-24

import regex

schema User:
    """
    User settings for Coder
    """
    name: str
    group: str = name
    home?: str = "/home/${name}"

schema Database:
    """
    Coder Database configuration
    """
    typ: "sqlite" | "postgresql" = "postgresql"
    host?: str = "127.0.0.1"
    port?: int = 5432
    database?: str = "coder"
    username?: str
    password?: str
    ssl_mode?: "require" | "disable" = "disable"
    path?: str = "/var/lib/coder/coder.db" if typ == "sqlite" else Undefined
    
    check:
        typ == "sqlite" or username != Undefined and len(username) > 0, "Database username required for ${typ}"
        typ == "sqlite" or password != Undefined and len(password) > 0, "Database password required for ${typ}"
        typ == "sqlite" or host != Undefined and len(host) > 0, "Database host required for ${typ}"

schema TLS:
    """
    TLS configuration for Coder
    """
    enabled: bool = False
    cert_file?: str
    key_file?: str
    address?: str = "0.0.0.0:443"
    
    check:
        not enabled or cert_file != Undefined and len(cert_file) > 0, "cert_file required when TLS enabled"
        not enabled or key_file != Undefined and len(key_file) > 0, "key_file required when TLS enabled"
        not enabled or (regex.match(cert_file, "^\/.*\.(pem|crt)$") if cert_file != Undefined else True), \
            "cert_file should be absolute path with .pem or .crt extension"
        not enabled or (regex.match(key_file, "^\/.*\.(pem|key)$") if key_file != Undefined else True), \
            "key_file should be absolute path with .pem or .key extension"

schema OAuth:
    """
    OAuth configuration for Coder
    """
    enabled: bool = False
    provider: "github" | "oidc" | "google" = "github"
    client_id?: str
    client_secret?: str
    issuer_url?: str
    scopes?: [str] = ["openid", "profile", "email"]
    
    check:
        not enabled or client_id != Undefined and len(client_id) > 0, "client_id required when OAuth enabled"
        not enabled or client_secret != Undefined and len(client_secret) > 0, "client_secret required when OAuth enabled"
        not enabled or provider != "oidc" or issuer_url != Undefined and len(issuer_url) > 0, "issuer_url required for OIDC provider"

schema CoderServer:
    """
    Coder server configuration
    """
    name: str = "coder"
    version: str
    run_user: User = {
        name = "coder"
    }
    work_path: str = "/var/lib/coder"
    config_path: str = "/etc/coder"
    run_path: str = "/usr/local/bin/coder"
    access_url: str
    wildcard_access_url?: str
    http_address: str = "0.0.0.0:7080"
    database: Database = {
        typ = "postgresql"
    }
    tls: TLS = {
        enabled = False
    }
    oauth: OAuth = {
        enabled = False
    }
    log_level: "trace" | "debug" | "info" | "warn" | "error" = "info"
    telemetry_enabled: bool = True
    update_check_enabled: bool = True
    redirect_to_access_url: bool = False
    proxy_trusted_headers: [str] = []
    proxy_trusted_origins: [str] = []
    secure_auth_cookie: bool = False
    max_session_token_lifetime: str = "24h"
    disable_password_auth: bool = False
    
    check:
        len(access_url) > 0, "access_url is required"
        regex.match(access_url, "^https?://.*$"), "access_url must be a valid HTTP/HTTPS URL"
        wildcard_access_url == Undefined or regex.match(wildcard_access_url, "^\*\..*$"), "wildcard_access_url must start with *."
        len(run_user.name) > 0, "Check run_user name"
        len(work_path) > 0, "Check work_path"
        len(config_path) > 0, "Check config_path"