#!/usr/bin/env nu 
# Info: Script to run Provisioning
# Author: JesusPerezLorenzo 
# Release: 1.0.4
# Date: 6-2-2024

#use std  # assert
use std log

use lib_provisioning * 

use servers/ssh.nu *
use infras/utils.nu *

use env.nu *

use infras *

use main_provisioning/ops.nu provisioning_infra_options

# - > Help on Infra
export def "main help" [
  --src: string = ""
  --notitles       # not tittles
  --out: string    #  Print Output format: json, yaml, text (default)
] { 
  if $notitles == null or not $notitles { show_titles } 
  ^($env.PROVISIONING_NAME) "-mod" "infra" "--help"
  if ($out | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = false }
  print (provisioning_infra_options)
  if not $env.PROVISIONING_DEBUG { end_run "" } 
}

# >  Infras with Tasks and Services for servers
def main [
  ...args: string  # Other options, use help to get info 
  --iptype: string = "public" # Ip type to connect
  -v               # Show version
  -i               # Show Info 
  --version (-V)   # Show version with title
  --info (-I)      # Show Info  with title
  --about (-a)     # Show About
  --infra (-i): string  # Infra directory 
  --infras: string # Infras list names  separated by commas
  --settings (-s): string # Settings path 
  --iptype: string = "public" # Ip type to connect
  --serverpos (-p): int   # Server position in settings 
  --check (-c)     # Only check mode no servers will be created 
  --yes (-y)       # Confirm task
  --wait (-w)      # Wait servers to be created 
  --select: string # Select with taskservice  as option 
  --onsel: string  # On selection: e (edit) | v (view) | l (list)
  --debug (-x)     # Use Debug mode
  --xm             # Debug with PROVISIONING_METADATA 
  --xc             # Debuc for taskservice and services locally PROVISIONING_DEBUG_CHECK 
  --xr             # Debug for remote servers PROVISIONING_DEBUG_REMOTE 
  --xld            # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug 
  --nc             # Not clean working settings 
  --metadata       # Error with metadata (-xm)
  --notitles       # Do not show banner titles
  --helpinfo (-h)  # For more details use options "help" (no dashes) 
  --out: string    #  Print Output format: json, yaml, text (default)
]: nothing -> nothing {
  if ($out | is-not-empty) {
    $env.PROVISIONING_OUT = $out 
    $env.PROVISIONING_NO_TERMINAL = true
  }
  provisioning_init $helpinfo "infra" $args
  if $version or $v { ^$env.PROVISIONING_NAME -v ; exit }
  if $info or $i { ^$env.PROVISIONING_NAME -i ; exit }
  if $about { 
    #use defs/about.nu [ about_info ]
    _print (get_about_info)  
    exit 
  }
  if $debug { $env.PROVISIONING_DEBUG = true } 
  if $metadata { $env.PROVISIONING_METADATA = true } 
  # for $arg in $args { print $arg  }
  let task = if ($args | length) > 0 { ($args| get 0) } else { "" } 
  let ops = $"($env.PROVISIONING_ARGS? | default "") " | str replace $" ($task) " "" | str trim
  let infras_list = if $infras != null { 
    $infras | split row ","
  } else if ($ops | split row " " | get -i 0 | str contains ",") {
    ($ops | split row " " | get -i 0 | split row ",") 
  } else if ($infra | is-not-empty) { 
    [ $infra ]
  } else { [] } 
  let ops = if ($ops | split row " " | get -i 0 | str contains ",") {
    ($ops | str replace ($ops | split row " " | get -i 0 ) "") 
  } else { $ops }
  let name = if ($ops | str starts-with "-") { "" } else { ($ops | split row "-" | find -v -r "^--" | get -i 0 | default "" | str trim) }
  match $task {
    "h" => { 
      exec ($env.PROVISIONING_NAME) "-mod" "taskserv" "help" "--notitles"
    },
    "ssh" => {
      #use servers/ssh.nu *
      #use utils/settings.nu *
      #let curr_settings = (find_get_settings --infra $infra --settings $settings)
      #server_ssh $curr_settings "" "pub"
      exec ($env.PROVISIONING_NAME) "-mod" "server" "status" ...($ops | split row " ") --notitles
    }
    "c" | "create" => { 
      let outfile = ""
      on_create_infras  $infras_list $check $wait $outfile $name $serverpos 
    }
    "d" | "delete" => { 
      if not $yes or not (($env.PROVISIONING_ARGS? | default "") | str contains "--yes")  {
        _print $"Run (_ansi red_bold)delete infras(_ansi reset) (_ansi cyan_bold)($infras_list)(_ansi reset) type (_ansi green_bold)yes(_ansi reset) ? " 
        let user_input = (input --numchar 3)
        if $user_input != "yes" and $user_input != "YES"  {
          exit 1
        }
      }
      let keep_storage = false
      on_delete_infras  $infras_list $keep_storage $wait $name $serverpos
    }
    "g" | "generate" => { 
      let outfile = ""
      on_generate_infras  $infras_list $check $wait $outfile $name $serverpos 
    }
    "t" | "taskserv" => { 
      let hostname = if ($ops | str starts-with "-") { "" } else { ($ops | split row "-" | find -v -r "^--" | get -i 1 | default "" | str trim) }
      on_taskserv_infras $infras_list $check $name $hostname --iptype $iptype
    }
    "cost" | "price" => { 
      let match_host = if ($name | str starts-with "-") { 
        ""
      } else { 
        $name
      }
      infras_walk_by $infras_list $match_host $check false
    }
    "list" => { 
      #use defs/lists.nu on_list
      on_list "infras" ($onsel | default "") ""
    },
    _ => { 
      invalid_task "infra" $task --end
    },
  } 
  if not $env.PROVISIONING_DEBUG { end_run "" } 
}