use ../config/accessor.nu *

export def ssh_cmd  [
  settings: record
  server: record
  with_bash: bool
  cmd: string
  live_ip: string
] {
  let ip = if $live_ip != ""  {
    $live_ip
  } else {
    #use ../../../../providers/prov_lib/middleware.nu mw_get_ip
    (mw_get_ip $settings $server ($server | get -o liveness_ip | default "public") false)
  }
  if $ip == "" { return false  }
  if not (check_connection $server $ip "ssh_cmd")  { return false }
  let remote_cmd = if $with_bash {
    let ops = if (is-debug-enabled) { "-x" } else { "" }
    $"bash ($ops) ($cmd)"
  } else { $cmd }
  let ssh_loglevel = if (is-debug-enabled) {
    _print $"Run ($remote_cmd) in ($server.installer_user)@($ip)"
    "-o LogLevel=info"
  } else {
    "-o LogLevel=quiet"
  }
  let ssh_op_0 = if ($env.SSH_OPS | length) > 0 { $env.SSH_OPS | get 0 } else { "" }
  let ssh_op_1 = if ($env.SSH_OPS | length) > 1 { $env.SSH_OPS | get 1 } else { "" }
  let res = (^ssh "-o" $ssh_op_0 "-o" $ssh_op_1 "-o" IdentitiesOnly=yes $ssh_loglevel
    "-i" ($server.ssh_key_path | str replace ".pub" "")
    $"($server.installer_user)@($ip)" ($remote_cmd) | complete)
  if $res.exit_code != 0 {
      _print $"❗ run ($remote_cmd) in ($server.hostname) errors ($res.stdout ) "
      return false
  }
  if (is-debug-enabled) and $remote_cmd != "ls" { _print $res.stdout }
  true
}
export def scp_to  [
  settings: record
  server: record
  source: list<string>
  target: string
  live_ip: string
] {
  let ip = if $live_ip != ""  {
    $live_ip
  } else {
    #use ../../../../providers/prov_lib/middleware.nu mw_get_ip
    (mw_get_ip $settings $server ($server | get -o liveness_ip | default "public") false)
  }
  if $ip == "" { return false }
  if not (check_connection $server $ip "scp_to")  { return false }
  let source_files = ($source | str join " ")
  let ssh_op_0 = if ($env.SSH_OPS | length) > 0 { $env.SSH_OPS | get 0 } else { "" }
  let ssh_op_1 = if ($env.SSH_OPS | length) > 1 { $env.SSH_OPS | get 1 } else { "" }
  let ssh_loglevel = if (is-debug-enabled) {
    _print $"Sending ($source | str join ' ') to ($server.installer_user)@($ip)/tmp/($target)"
    _print $"scp -o ($ssh_op_0) -o ($ssh_op_1) -o IdentitiesOnly=yes -i ($server.ssh_key_path | str replace ".pub" "") ($source_files) ($server.installer_user)@($ip):($target)"
    "-o LogLevel=info"
  } else {
    "-o LogLevel=quiet"
  }
  let res = (^scp "-o" $ssh_op_0 "-o" $ssh_op_1 "-o" IdentitiesOnly=yes  $ssh_loglevel
    "-i" ($server.ssh_key_path | str replace ".pub" "")
    $source_files $"($server.installer_user)@($ip):($target)" | complete)
  if $res.exit_code != 0 {
      _print $"❗ copy ($target | str join  ' ') to  ($server.hostname) errors ($res.stdout ) "
      return false
  }
  if (is-debug-enabled) { _print $res.stdout }
  true
}
export def scp_from  [
  settings: record
  server: record
  source: string
  target: string
  live_ip: string
] {
  let ip = if $live_ip != ""  {
    $live_ip
  } else {
    #use ../../../../providers/prov_lib/middleware.nu mw_get_ip
    (mw_get_ip $settings $server ($server | get -o liveness_ip | default "public") false)
  }
  if $ip == "" { return false }
  if not (check_connection $server $ip "scp_from")  { return false }
  let ssh_op_0 = if ($env.SSH_OPS | length) > 0 { $env.SSH_OPS | get 0 } else { "" }
  let ssh_op_1 = if ($env.SSH_OPS | length) > 1 { $env.SSH_OPS | get 1 } else { "" }
  let ssh_loglevel = if (is-debug-enabled) {
    _print $"Getting ($target | str join ' ') from ($server.installer_user)@($ip)/tmp/($target)"
    "-o LogLevel=info"
  } else {
    "-o LogLevel=quiet"
  }
  let res = (^scp "-o" $ssh_op_0 "-o" $ssh_op_1 "-o" IdentitiesOnly=yes  $ssh_loglevel
    "-i" ($server.ssh_key_path | str replace ".pub" "")
    $"($server.installer_user)@($ip):($source)" $target | complete)
  if $res.exit_code != 0 {
      _print $"❗ copy ($source) from ($server.hostname) to ($target) errors ($res.stdout ) "
      return false
  }
  if (is-debug-enabled) { _print $res.stdout }
  true
}
export def ssh_cp_run  [
  settings: record
  server: record
  source: list<string>
  target: string
  with_bash: bool
  live_ip: string
  ssh_remove: bool
] {
  let ip = if $live_ip != ""  {
    $live_ip
  } else {
    #use ../../../../providers/prov_lib/middleware.nu mw_get_ip
    (mw_get_ip $settings $server ($server | get -o liveness_ip | default "public") false)
  }
  if $ip == "" {
    _print $"❗ ssh_cp_run (_ansi red_bold)No IP(_ansi reset) to (_ansi green_bold)($server.hostname)(_ansi reset)"
    return false
  }
  if not (scp_to $settings $server $source $target $ip) { return false }
  if not (ssh_cmd $settings $server $with_bash $target $ip) { return false }
  if $env.PROVISIONING_SSH_DEBUG? != null and $env.PROVISIONING_SSH_DEBUG { return true }
  if $ssh_remove {
    return (ssh_cmd $settings $server false $"rm -f ($target)" $ip)
  }
  true
}
export def check_connection [
  server: record
  ip: string
  origin: string
] {
  if not (port_scan $ip ($server | get -o liveness_port | default 22) 1) {
      _print (
        $"\n🛑 (_ansi red)Error connection(_ansi reset) ($origin) (_ansi blue)($server.hostname)(_ansi reset) " +
        $"(_ansi blue_bold)($ip)(_ansi reset) at ($server | get -o liveness_port | default 22) (_ansi red_bold)failed(_ansi reset) "
      )
      return false
  }
  true
}
