use lib_provisioning *
use create.nu * 
use servers/delete.nu * 
use handlers.nu * 
#use ../lib_provisioning/utils ssh_cmd
export def on_create_infras [
    infras_list: list      # infras list
    check: bool        # Only check mode no servers will be created 
    wait: bool         # Wait for creation
    outfile?: string   # Out file for creation
    hostname?: string  # Server hostname in settings
    serverpos?: int    # Server position in settings 
] { 
    let create_infra = {|infra| 
        if not ($env.PROVISIONING_INFRA_PATH | path join $infra.item | path exists) {
            print $"\n🛑 Path not found for (_ansi red)($infra.item)(_ansi reset) in (_ansi cyan)($env.PROVISIONING_KLOUD_PATH)(_ansi reset)"
        } else { 
            let settings = (find_get_settings --infra $infra.item)
            on_infra $infra $settings $check $wait $outfile $hostname $serverpos
        } 
    }
    if $check {  
        $infras_list | enumerate | each { |infra|  do $create_infra $infra }
    } else { 
        $infras_list | enumerate | par-each { |infra|  do $create_infra $infra }
    }
}
export def on_infra [
    infra: record
    settings: record
    check: bool
    wait: bool
    outfile?: string   # Out file for creation
    hostname?: string  # Server hostname in settings
    serverpos?: int    # Server position in settings 
] { 
    print "TODO on_infra"
    print $infra
}
export def on_taskserv_infras [
    infras_list: list      # infras list
    check: bool        # Only check mode no servers will be created 
    name?: string
    server?: string 
    --iptype: string = "public" # Ip type to connect
] { 
    let run_create = { |infra| 
        let curr_settings = (find_get_settings --infra $infra)
        $env.WK_CNPROV = $curr_settings.wk_path
        let match_task = if $name == null or $name == "" { "" } else { $name } 
        let match_server = if $server == null or $server == "" { "" } else { $server} 
        on_taskservs $curr_settings $match_task $match_server $iptype $check
    }
    $infras_list | enumerate | par-each { |infra|  
        let task = { do $run_create $infra.item }
        let result = desktop_run_notify $"($env.PROVISIONING_NAME) ($infra.item) taskservs create" "-> " $task --timeout 11sec
    }
}
export def on_delete_infras [
    infras_list: list      # infras list
    keep_storage:  bool    # keepstorage
    wait: bool         # Wait for creation
    name?: string  # Server hostname in settings
    serverpos?: int    # Server position in settings 
] { 
    let run_delete = { |infra, keepstorage| 
        let curr_settings = (find_get_settings --infra $infra)
        on_delete_servers $curr_settings $keepstorage $wait $name $serverpos 
    }
    $infras_list | enumerate | par-each { |infra|  
        let task = { do $run_delete $infra.item $keep_storage }
        let result = desktop_run_notify $"($env.PROVISIONING_NAME) ($infra.item) servers delete" "-> " $task --timeout 11sec
    }
}
export def on_generate_infras [
    infras_list: list      # infras list
    keep_storage:  bool    # keepstorage
    wait: bool         # Wait for creation
    name?: string  # Server hostname in settings
    serverpos?: int    # Server position in settings 
] { 
    print "TODO on_generate_infras"
    #  let curr_settings = (find_get_settings --infra $infra)
}
export def infras_walk_by [
    infras_list: list
    match_hostname: string 
    check: bool        # Only check mode no servers will be created 
    return_no_exists: bool
] {
    mut infra_servers = {}
    mut total_month = 0
    mut total_hour = 0
    mut total_day = 0
    mut table_items = []
    let sum_color  = { fg: '#0000ff' bg: '#dadada' attr: b }
    let total_color  = { fg: '#ffff00' bg: '#0000ff' attr: b }
    print $"(_ansi purple_reverse) Cost ($infras_list | str join ' ')(_ansi reset) "
    for infra in $infras_list {
        if not ($env.PROVISIONING_INFRA_PATH | path join $infra | path exists) {
            print $"\n🛑 Path not found for (_ansi red)($infra)(_ansi reset) in (_ansi cyan)($env.PROVISIONING_KLOUD_PATH)(_ansi reset)"
            continue
        }
        let settings = (find_get_settings --infra $infra)
        mut c_infra_servers = {}
        mut c_total_month = 0
        mut c_total_hour = 0
        mut c_total_day = 0
        for server in $settings.data.servers {  
            if $match_hostname != null and $match_hostname != "" and $server.hostname != $match_hostname  { 
                continue
            }
            if ($infra_servers | get -o $server.provider | is-empty) { 
                $infra_servers = ($infra_servers | merge { $server.provider: ($server false)} ) 
            }
            let item = (mw_get_infra_item $server $settings $infra_servers false) 
            if  $env.PROVISIONING_DEBUG_CHECK { print ($item | table -e)}
            let price_month = (mw_get_infra_price $server $item "month" false | default 0)
            let price_hour = (mw_get_infra_price $server $item "hour" false | default 0)
            let price_day = ($price_hour * 24)
            $total_month += $price_month
            $total_hour += $price_hour
            $total_day += ($price_day)
            $c_total_month += $price_month
            $c_total_hour += $price_hour
            $c_total_day += ($price_day)
            let already_created = (mw_server_exists $server false) 
            let host_color = if $already_created { "green_bold" } else { "red" }
            $table_items = ($table_items | append {
                host: $"(_ansi $host_color)($server.hostname)(_ansi reset) (_ansi blue_bold)($server.plan)(_ansi reset)", 
                prov: $"(_ansi default_bold) ($server.provider) (_ansi reset)",
                hour: $"(_ansi default_bold)  ($price_hour)€  (_ansi reset)",
                day: $"(_ansi default_bold)  ($price_day | math round -p 4)€  (_ansi reset)",
                month: $"(_ansi default_bold)  ($price_month)€ (_ansi reset)"
            })
            if not $check {
                if not ($already_created) {
                    if $return_no_exists {
                        return { status: false, error: $"($server.hostname) not created" }
                        #} else {
                        #print $"(_ansi red_bold)($server.hostname)(_ansi reset) not created"
                    }
                }
            }
        }
        rm -rf $settings.wk_path
        $table_items = ($table_items | append {
            host: $"(_ansi --escape $sum_color)   ($settings.infra)  (_ansi reset)", 
            prov: $"(_ansi default_bold) (_ansi reset)",
            hour: $"(_ansi --escape $sum_color)  ($c_total_hour | math round -p 4)€  (_ansi reset)",
            day:  $"(_ansi --escape $sum_color)  ($c_total_day | math round -p 4)€  (_ansi reset)",
            month:$"(_ansi --escape $sum_color)  ($c_total_month)€  (_ansi reset)"
        })
    }
    $table_items = ($table_items | append { host: "", prov: "", month: "", day: "", hour: ""})
    $table_items = ($table_items | append {
        host: $"(_ansi --escape $total_color)   TOTAL  (_ansi reset)", 
        prov: $"(_ansi default_bold) (_ansi reset)",
        hour: $"(_ansi --escape $total_color)  ($total_hour | math round -p 4)€  (_ansi reset)",
        day:  $"(_ansi --escape $total_color)  ($total_day | math round -p 4)€  (_ansi reset)",
        month:$"(_ansi --escape $total_color)  ($total_month)€  (_ansi reset)"
    })
    _print ($table_items | table -i false)
}
