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

import regex

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

schema ValidatorAccount:
    """
    Validator account configuration (Stash/Controller)
    """
    stash_address?: str
    controller_address?: str
    reward_destination: "Staked" | "Stash" | "Controller" | "Account" = "Staked"
    commission: int = 0  # Commission percentage (0-100)
    
    check:
        0 <= commission <= 100, "Commission must be between 0 and 100"

schema SessionKeys:
    """
    Session keys configuration
    """
    keys_file?: str = "/var/lib/polkadot/session-keys"
    auto_rotate: bool = False
    rotation_interval?: int = 86400  # seconds (24 hours)
    babe_key?: str
    grandpa_key?: str
    im_online_key?: str
    para_validator_key?: str
    para_assignment_key?: str
    authority_discovery_key?: str
    
    check:
        rotation_interval == Undefined or rotation_interval > 0, "Rotation interval must be positive"

schema Network:
    """
    Network configuration for validator
    """
    chain: "polkadot" | "kusama" | "westend" = "polkadot"
    listen_addr: str = "/ip4/0.0.0.0/tcp/30333"
    public_addr?: str
    node_key_file?: str = "/var/lib/polkadot/node-key"
    bootnodes: [str] = []
    reserved_nodes: [str] = []
    reserved_only: bool = False
    max_peers: int = 50
    max_peers_light: int = 100
    
    check:
        max_peers > 0, "max_peers must be positive"
        max_peers_light > 0, "max_peers_light must be positive"

schema RPC:
    """
    RPC configuration (restricted for validators)
    """
    enabled: bool = True
    bind_addr: str = "127.0.0.1"  # Localhost only for security
    port: int = 9944
    ws_port: int = 9944
    http_port: int = 9933
    max_connections: int = 10  # Limited for validators
    cors: [str] = []  # No CORS for validators
    methods: [str] = ["safe"]  # Only safe methods
    
    check:
        1 <= port <= 65535, "RPC port must be between 1 and 65535"
        1 <= ws_port <= 65535, "WebSocket port must be between 1 and 65535"
        1 <= http_port <= 65535, "HTTP port must be between 1 and 65535"
        max_connections <= 50, "Validator RPC connections should be limited"

schema Monitoring:
    """
    Monitoring configuration for validator
    """
    enabled: bool = True
    prometheus_port: int = 9615
    prometheus_bind_addr: str = "127.0.0.1"
    telemetry_enabled: bool = True
    telemetry_url: str = "wss://telemetry.polkadot.io/submit/"
    telemetry_verbosity: int = 0
    
    check:
        1 <= prometheus_port <= 65535, "Prometheus port must be between 1 and 65535"
        0 <= telemetry_verbosity <= 9, "Telemetry verbosity must be between 0 and 9"

schema Security:
    """
    Security configuration for validator
    """
    enable_firewall: bool = True
    allowed_ssh_ips: [str] = []
    fail2ban_enabled: bool = True
    auto_updates: bool = True
    secure_keystore: bool = True
    backup_keys: bool = True
    backup_path?: str = "/var/backups/polkadot"

schema PolkadotValidator:
    """
    Polkadot validator node configuration
    """
    name: str = "polkadot-validator"
    version: str = "latest"
    run_user: User = {
        name = "polkadot"
    }
    work_path: str = "/var/lib/polkadot"
    config_path: str = "/etc/polkadot"
    bin_path: str = "/usr/local/bin/polkadot"
    base_path: str = "/var/lib/polkadot/data"
    keystore_path: str = "/var/lib/polkadot/keystore"
    validator_accounts: ValidatorAccount = {}
    session_keys: SessionKeys = {}
    network: Network = {}
    rpc: RPC = {}
    monitoring: Monitoring = {}
    security: Security = {}
    log_level: "error" | "warn" | "info" | "debug" | "trace" = "info"
    log_targets: [str] = ["runtime::system"]
    execution: "native" | "wasm" | "both" = "wasm"
    wasm_execution: "compiled" | "interpreted" = "compiled"
    state_cache_size: int = 134217728  # 128MB for validators
    db_cache: int = 2048  # 2GB for validators
    pruning: "archive" | int = 1000  # Keep more blocks for validators
    unsafe_pruning: bool = False
    
    check:
        len(run_user.name) > 0, "Check run_user name"
        len(work_path) > 0, "Check work_path"
        len(config_path) > 0, "Check config_path"
        len(base_path) > 0, "Check base_path"
        state_cache_size > 0, "state_cache_size must be positive"
        db_cache > 0, "db_cache must be positive"
        not unsafe_pruning or pruning != "archive", "Cannot use unsafe pruning with archive mode"