use utils.nu servers_selector

#use clusters/run.nu run_cluster
def install_from_server  [
    defs: record
    server_cluster_path: string
    wk_server: string
]: nothing -> bool {
    _print $"($defs.cluster.name) on ($defs.server.hostname) install (_ansi purple_bold)from ($defs.cluster_install_mode)(_ansi reset)"
    run_cluster $defs ($env.PROVISIONING_RUN_CLUSTERS_PATH | path join $defs.cluster.name | path join $server_cluster_path) 
        ($wk_server | path join $defs.cluster.name)
}
def install_from_library  [
    defs: record
    server_cluster_path: string
    wk_server: string
]: nothing -> bool {
    _print $"($defs.cluster.name) on ($defs.server.hostname) installed (_ansi purple_bold)from library(_ansi reset)"
    run_cluster $defs ($env.PROVISIONING_CLUSTERS_PATH |path join $defs.cluster.name | path join $defs.cluster_profile) 
        ($wk_server | path join $defs.cluster.name)
}

export def on_clusters [
    settings: record
    match_cluster: string  
    match_server: string  
    iptype: string
    check: bool
]: nothing -> bool {
    #  use ../../../providers/prov_lib/middleware.nu  mw_get_ip 
    _print $"Running (_ansi yellow_bold)clusters(_ansi reset) ..."
    if $env.PROVISIONING_SOPS? == null  {
        # A SOPS load env 
        $env.CURRENT_INFRA_PATH = $"($settings.infra_path)/($settings.infra)"
        use sops_env.nu  
    }
    let ip_type = if $iptype == "" { "public" } else { $iptype }
    mut server_pos = -1
    mut cluster_pos = -1
    mut curr_cluster = 0
    let created_clusters_dirpath = ( $settings.data.created_clusters_dirpath | default "/tmp" | 
        str replace "./" $"($settings.src_path)/" | str replace "~" $env.HOME | str replace "NOW" $env.NOW 
    )
    let root_wk_server = ($created_clusters_dirpath | path join "on-server")
    if not ($root_wk_server | path exists ) { ^mkdir "-p" $root_wk_server }
    let dflt_clean_created_clusters = ($settings.data.defaults_servers.clean_created_clusters? | default $created_clusters_dirpath | 
        str replace "./" $"($settings.src_path)/" | str replace "~" $env.HOME 
    )
    let run_ops = if  $env.PROVISIONING_DEBUG { "bash -x" } else { "" }
    for srvr in $settings.data.servers  {
        # continue
        _print $"on (_ansi green_bold)($srvr.hostname)(_ansi reset) ..."
        $server_pos += 1
        $cluster_pos = -1
        _print $"On server ($srvr.hostname) pos ($server_pos) ..."
        if $match_server != "" and $srvr.hostname != $match_server { continue } 
        let clean_created_clusters = (($settings.data.servers | get -o $server_pos).clean_created_clusters? | default $dflt_clean_created_clusters )
        let ip = if $env.PROVISIONING_DEBUG_CHECK { 
            "127.0.0.1"
        } else { 
            let curr_ip = (mw_get_ip $settings $srvr $ip_type false | default "")
            if $curr_ip == "" { 
                _print $"🛑 No IP ($ip_type) found for (_ansi green_bold)($srvr.hostname)(_ansi reset) ($server_pos) " 
                continue
            }
            #use utils.nu wait_for_server 
            if not (wait_for_server $server_pos $srvr $settings $curr_ip) { 
                print $"🛑 server ($srvr.hostname) ($curr_ip)  (_ansi red_bold)not in running state(_ansi reset)" 
                continue  
            }
            $curr_ip
        }
        let server = ($srvr | merge { ip_addresses: { pub: $ip, priv: $srvr.network_private_ip }})
        let wk_server  = ($root_wk_server | path join $server.hostname)
        if ($wk_server | path exists )  { rm -rf  $wk_server }
        ^mkdir "-p" $wk_server
        for cluster in $server.clusters  { 
            $cluster_pos += 1 
            if $cluster_pos > $curr_cluster { break }
            $curr_cluster += 1
            if $match_cluster  !=  "" and $match_cluster != $cluster.name { continue } 
            if not ($env.PROVISIONING_CLUSTERS_PATH | path join $cluster.name | path exists) { 
                print $"cluster path: ($env.PROVISIONING_CLUSTERS_PATH | path join $cluster.name) (_ansi red_bold)not found(_ansi reset)" 
                continue
            }
            if not ($wk_server | path join $cluster.name| path exists)  { ^mkdir "-p" ($wk_server | path join $cluster.name) }
            let $cluster_profile = if $cluster.profile == "" { "default" } else { $cluster.profile }
            let $cluster_install_mode = if $cluster.install_mode == "" { "library" } else { $cluster.install_mode }
            let server_cluster_path = ($server.hostname | path join $cluster_profile)
            let defs = { 
                settings: $settings, server: $server, cluster: $cluster, 
                cluster_install_mode: $cluster_install_mode, cluster_profile: $cluster_profile,
                pos: { server: $"($server_pos)", cluster: $cluster_pos}, ip: $ip }
            match $cluster.install_mode {
                "server" | "getfile" => { 
                    (install_from_server $defs $server_cluster_path $wk_server )
                },
                "library-server" => { 
                    (install_from_library $defs $server_cluster_path $wk_server)
                    (install_from_server $defs $server_cluster_path $wk_server )
                },
                "server-library" => { 
                    (install_from_server $defs $server_cluster_path $wk_server )
                    (install_from_library $defs $server_cluster_path $wk_server)
                },
                "library" => { 
                    (install_from_library $defs $server_cluster_path $wk_server)
                },
            }
            if $clean_created_clusters == "yes" { rm -rf ($wk_server | pth join $cluster.name) }
        }
        if $clean_created_clusters == "yes" { rm -rf $wk_server }
        print $"Clusters completed on ($server.hostname)"
    }
    if ("/tmp/k8s_join.sh"  | path exists) { cp "/tmp/k8s_join.sh" $root_wk_server ;  rm -r /tmp/k8s_join.sh }
    if $dflt_clean_created_clusters == "yes" { rm -rf $root_wk_server }
    print $"✅ Clusters (_ansi green_bold)completed(_ansi reset) ....."
    #use utils.nu servers_selector
    servers_selector $settings $ip_type false
    true
}
