use std
# Selective imports (ADR-025 Phase 3 Layer 2).
use lib_provisioning/config/accessor/core.nu [config-get]
use lib_provisioning/secrets/lib.nu [decode_secret_file]
use ../secrets/lib.nu get_secret_provider

export def find_file [
    start_path: string
    match_path: string
    only_first: bool
] {
    mut found_path = ""
    mut search_path = $start_path
    let home_root = ($env.HOME | path dirname)
    while $found_path == "" and  $search_path != "/" and $search_path != $home_root {
        if $search_path == "" { break }
        let res = if $only_first {
            (^find $search_path -type f -name $match_path -print -quit | complete)
        } else {
            (^find $search_path -type f -name $match_path err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
        }
    if $res.exit_code == 0 { $found_path = ($res.stdout | str trim )  }
        $search_path = ($search_path | path dirname)
    }
    $found_path
}
export def copy_file [
    source: string
    target: string
    quiet: bool
] {
    let provider = (get_secret_provider)
    if $provider == "" or ((config-get "sops.use_sops" "age") == "" and $env.PROVISIONING_USE_KMS == "") {
        let ops = if $quiet { "" } else { "-v" }
        cp $ops $source $target
        return
    }
    (decode_secret_file $source $target $quiet)
}
export def copy_prov_files [
    src_root: string
    src_path: string
    target: string
    no_replace: bool
    quiet: bool
] {
    mut path_name = ""
    let start_path = if $src_path == ""  or $src_path == "." { $src_root } else { ($src_root | path join $src_path) } | str replace "." $env.PWD
    let p = ($start_path | path type)
    if not ($start_path | path exists)  { return }
    if ($start_path | path type) != "dir" {
        # if ($"($target)/($path_name)" | path exists ) and $no_replace { return }
        copy_file $start_path $target $quiet
        return
    }
    for item in (glob ($start_path | path join "*")) {
        $path_name = ($item | path basename)
        if ($item | path type) == "dir" {
            if not ($target | path join $path_name | path exists) { ^mkdir -p ($target | path join $path_name) }
            copy_prov_files ($item | path dirname) $path_name ($target | path join $path_name) $no_replace $quiet
        } else if ($item | path exists) {
            if ($target | path join $path_name| path exists ) and $no_replace { continue }
            if not ($target | path exists) { ^mkdir -p $target }
            copy_file $item ($target | path join $path_name) $quiet
        }
    }
}
export def select_file_list [
    root_path: string
    title: string
    is_for_task: bool
    recursive_cnt: int
] {
    if (($env | get PROVISIONING_OUT? | default "" | is-not-empty)) or $env.PROVISIONING_NO_TERMINAL { return "" }
    if not ($root_path | path dirname | path exists) { return {} }
    _print $"(_ansi purple_bold)($title)(_ansi reset) ($root_path) "
    if (glob $root_path | length) == 0 { return {} }
    let pick_list = (ls ($root_path | into glob) | default [])
    let msg_sel = if $is_for_task {
        "Select one file"
    } else {
        "To use a file select one"
    }
    if ($pick_list | length) == 0 { return "" }
    let selection = if ($pick_list | length) > 1 {
        let prompt = $"(_ansi default_dimmed)($msg_sel) \(use arrows and press [enter] or [esc] to cancel\):(_ansi reset)"
        let pos_select = ($pick_list | each {|it| $"($it.modified) -> ($it.name | path basename)"} |input list --index $prompt)
        if $pos_select == null { return null }
        let selection = if ($pick_list | length) > $pos_select { $pick_list | get $pos_select } else { null }
        if not $is_for_task  {
            _print $"\nFor (_ansi green_bold)($selection.name)(_ansi reset) file use:"
        }
        $selection
    } else {
        let selection = if ($pick_list | is-empty) { null } else { $pick_list | first }
        if not $is_for_task  {
            _print $"\n(_ansi default_dimmed)For a file (_ansi reset)(_ansi green_bold)($selection.name)(_ansi reset) use:"
        }
        $selection
    }
    let file_selection = if $selection.type == "dir" {
        let cnt = if $recursive_cnt > 0 {
            # print $recursive_cnt
            if ($recursive_cnt - 1) == 0 { return $selection }
            $recursive_cnt - 1
        } else { $recursive_cnt }
        return (select_file_list $selection.name $title $is_for_task $cnt)
    } else {
        $selection
    }
    if not $is_for_task  {
        show_clip_to $"($file_selection.name)" true
    }
    $file_selection
}
