use std
use utils select_file_list

export def deploy_remove [
    settings: record
    str_match?: string
]: nothing -> nothing {
    let match = if $str_match != "" { $str_match |str trim } else { (date now | format date ($env.PROVISIONING_MATCH_DATE? | default "%Y_%m_%d")) }
    let str_out_path = ($settings.data.runset.output_path | default "" |  str replace "~" $env.HOME | str replace "NOW" $match)
    let prov_local_bin_path = ($settings.data.prov_local_bin_path | default "" | str replace "~" $env.HOME )
    if $prov_local_bin_path  != "" and ($prov_local_bin_path | path join "on_deploy_remove" | path exists ) {
        ^($prov_local_bin_path | path join "on_deploy_remove")
    }
    let out_path = if ($str_out_path | str starts-with "/") { $str_out_path
    } else { ($settings.infra_path | path join $settings.infra | path join $str_out_path) }

    if $out_path == "" or not ($out_path | path dirname | path exists ) { return }
    mut last_provider = ""
    for server in $settings.data.servers {
        let provider = $server.provider | default ""
        if $provider == $last_provider {
            continue
        } else {
            $last_provider = $provider
        }
        if (".git" | path exists) or (".." | path join ".git" | path exists) {
            ^git rm -rf ($out_path | path dirname | path join $"($provider)_cmd.*") | ignore
        }
        let res = (^rm -rf ...(glob ($out_path | path dirname | path join $"($provider)_cmd.*")) | complete)
        if $res.exit_code == 0 {
            print $"(_ansi purple_bold)Deploy files(_ansi reset) ($out_path | path dirname | path join $"($provider)_cmd.*") (_ansi red)removed(_ansi reset)"
        }
    }
    if (".git" | path exists) or (".." | path join ".git" | path exists) {
        ^git rm -rf ...(glob ($out_path | path dirname | path join $"($match)_*")) | ignore
    }
    let result = (^rm -rf ...(glob ($out_path | path dirname | path join $"($match)_*")) | complete)
    if $result.exit_code == 0 {
        print $"(_ansi purple_bold)Deploy files(_ansi reset) ($out_path | path dirname | path join $"($match)_*") (_ansi red)removed(_ansi reset)"
    }
}

export def on_item_for_cli [
   item: string
   item_name: string
   task: string
   task_name: string
   task_cmd: string
   show_msg: bool
   show_sel: bool
]: nothing -> nothing {
    if $show_sel { print $"\n($item)" }
    let full_cmd = if ($task_cmd | str starts-with "ls ") { $'nu -c "($task_cmd) ($item)" ' } else { $'($task_cmd) ($item)'}
    if ($task_name | is-not-empty) {
        print $"($task_name) ($task_cmd) (_ansi purple_bold)($item_name)(_ansi reset) by paste in command line"
    }
    show_clip_to $full_cmd $show_msg
}
export def deploy_list [
    settings: record
    str_match: string
    onsel: string
]: nothing -> nothing {
    let match = if $str_match != "" { $str_match |str trim } else { (date now | format date ($env.PROVISIONING_MATCH_DATE? | default "%Y_%m_%d")) }
    let str_out_path = ($settings.data.runset.output_path | default "" |  str replace "~" $env.HOME | str replace "NOW" $match)
    let prov_local_bin_path = ($settings.data.prov_local_bin_path | default "" | str replace "~" $env.HOME )
    let out_path = if ($str_out_path | str starts-with "/") { $str_out_path
        } else { ($settings.infra_path | path join $settings.infra | path join $str_out_path) }
    if $out_path == "" or not ($out_path | path dirname | path exists ) { return }
    let selection = match $onsel {
        "edit" | "editor" | "ed" | "e" => {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "view"| "vw" | "v" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "list"| "ls" | "l" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "tree"| "tr" | "t" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "code"| "c" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "shell"| "s" | "sh" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        "nu"| "n" =>  {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        },
        _ => {
            select_file_list ($out_path | path dirname | path join $"($match)*") "Deploy files" true -1
        }
    }
    if ($selection | is-not-empty ) {
        match $onsel {
            "edit" | "editor" | "ed" | "e" => {
                let cmd = ($env | get -o EDITOR | default "vi")
                run-external $cmd $selection.name
                on_item_for_cli  $selection.name ($selection.name | path basename) "edit" "Edit" $cmd false true
            },
            "view"| "vw" | "v" =>  {
                let cmd = if (^bash -c "type -P bat" | is-not-empty) { "bat" } else { "cat" }
                run-external $cmd $selection.name
                on_item_for_cli  $selection.name ($selection.name | path basename) "view" "View" $cmd false true
            },
            "list"| "ls" | "l" =>  {
                let cmd = if (^bash -c "type -P nu" | is-not-empty) { "ls -s" } else { "ls -l" }
                let file_path = if $selection.type == "file" {
                    ($selection.name | path dirname)
                } else { $selection.name}
                run-external nu "-c" $"($cmd) ($file_path)"
                on_item_for_cli  $file_path ($file_path | path basename) "list" "List" $cmd false false
            },
            "tree"| "tr" | "t" =>  {
                let cmd = if (^bash -c "type -P tree" | is-not-empty) { "tree -L 3" } else { "ls -s" }
                let file_path = if $selection.type == "file" {
                    $selection.name | path dirname
                } else { $selection.name}
                run-external nu "-c" $"($cmd) ($file_path)"
                on_item_for_cli  $file_path ($file_path | path basename) "tree" "Tree" $cmd false false
            },
            "code"| "c" =>  {
                let file_path = if $selection.type == "file" {
                    $selection.name | path dirname
                } else { $selection.name}
                let cmd = $"code ($file_path)"
                run-external code $file_path
                show_titles
                print "Command "
                on_item_for_cli  $file_path ($file_path | path basename) "tree" "Tree" $cmd false false
            },
            "shell" | "sh" | "s"  =>  {
                let file_path = if $selection.type == "file" {
                    $selection.name | path dirname
                } else { $selection.name}
                let cmd = $"bash -c " + $"cd ($file_path) ; ($env.SHELL)"
                print $"(_ansi default_dimmed)Use [ctrl-d] or 'exit' to end with(_ansi reset) ($env.SHELL)"
                run-external bash "-c" $"cd ($file_path) ; ($env.SHELL)"
                show_titles
                print "Command "
                on_item_for_cli  $file_path ($file_path | path basename) "shell" "shell" $cmd false false
            },
            "nu"| "n" =>  {
                let file_path = if $selection.type == "file" {
                    $selection.name | path dirname
                } else { $selection.name}
                let cmd = $"($env.NU) -i -e " + $"cd ($file_path)"
                print $"(_ansi default_dimmed)Use [ctrl-d] or 'exit' to end with(_ansi reset) nushell\n"
                run-external nu "-i" "-e" $"cd ($file_path)"
                on_item_for_cli  $file_path ($file_path | path basename) "nu" "nushell" $cmd false false
            },
            _ => {
                on_item_for_cli  $selection.name ($selection.name | path basename) "" "" "" false false
                print $selection
            }
        }
    }
    for server in $settings.data.servers {
        let provider = $server.provider | default ""
        ^ls ($out_path | path dirname | path join $"($provider)_cmd.*") err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" })
    }
}
