
use ops.nu provisioning_context_options

use ../lib_provisioning/setup *

#> Manage contexts settings 
export def "main context" [
  task?: string    # server (s) | task (t) | service (sv)
  name?: string    # server (s) | task (t) | service (sv)
  --key (-k): string
  --value (-v): string
  ...args          # Args for create command 
  --reset (-r)     # Restore defaults
  --serverpos (-p): int  # Server position in settings 
  --wait (-w)      # Wait servers to be created 
  --settings (-s): string # Settings path 
  --outfile (-o): string  # Output file
  --debug (-x)     # Use Debug mode
  --xm             # Debug with PROVISIONING_METADATA 
  --xc             # Debuc for task and services locally PROVISIONING_DEBUG_CHECK 
  --xr             # Debug for remote servers PROVISIONING_DEBUG_REMOTE 
  --xld            # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug 
  --metadata       # Error with metadata (-xm)
  --notitles       # not tittles
] {
  parse_help_command "context" --task {provisioning_context_options} --end
  if $debug { $env.PROVISIONING_DEBUG = true } 
  let config_path = (setup_config_path) 
  let default_context_path = ($config_path | path join "default_context.yaml")
  let name_context_path = ($config_path | path join $"($name).yaml")
  let context_path = ($config_path | path join "context.yaml")
  let set_as_default = { 
    rm -f $context_path
    ^ln -s $name_context_path $context_path
    _print (
        $"(_ansi blue_bold)($name)(_ansi reset) set as (_ansi green)default context(_ansi reset)" + 
        $" in (_ansi default_dimmed)($config_path)(_ansi reset)"
      )
  }
  match $task { 
    "h" => { 
      ^$"($env.PROVISIONING_NAME)" context --help
      _print (provisioning_context_options)
    }
    "create" | "c" | "new" => { 
      if $name == null or $name == "" { 
        _print $"🛑 No (_ansi red)name(_ansi reset) value " 
      }
      if ($name_context_path |path exists) {
        _print $"(_ansi blue_bold)($name)(_ansi reset) already in (_ansi default_dimmed)($config_path)(_ansi reset)"
      } else {
        ^cp  $default_context_path $name_context_path
        open -r $name_context_path | str replace "infra: " $"infra: ($name)" | save -f $name_context_path
        _print $"(_ansi blue_bold)($name)(_ansi reset) created in (_ansi default_dimmed)($config_path)(_ansi reset)"
      }
      do $set_as_default
    },
    "default" | "d" => { 
      if $name == null or $name == "" { 
        _print $"🛑 No (_ansi red)name(_ansi reset) value " 
        exit 1
      }
      if not ($name_context_path | path exists) {
        _print $"🛑 No (_ansi red)($name)(_ansi reset) found in (_ansi default_dimmed)($config_path)(_ansi reset) " 
        exit 1
      }
      do $set_as_default
    },
    "remove" | "r" => { 
      if $name == null {
        _print $"🛑 No (_ansi red)name(_ansi reset) value " 
        exit 1
      }
      if $name == "" or not ( $name_context_path | path exists) { 
        _print $"🛑 context path (_ansi blue_bold)($name)(_ansi reset) not found "
        exit 1
      }
      let context = (setup_user_context $name) 
      let curr_infra = ($context | get -o "infra") 
      if $curr_infra == $name {
        _print (
          $"(_ansi blue_bold)($name)(_ansi reset) removed as (_ansi green)default context(_ansi reset) " +
          $" in (_ansi default_dimmed)($config_path)(_ansi reset)"
        )
      }
      rm -f $name_context_path $context_path
      _print $"(_ansi blue_bold)($name)(_ansi reset) context removed "
    },
    "edit" | "e" => { 
      let editor = ($env | get -o EDITOR | default "vi")
      let config_path = (setup_user_context_path $name)
      ^$editor $config_path
    }, 
    "view" | "v" => { 
        _print ((setup_user_context $name) | table -e)
    }, 
    "set" | "s" => { 
      let context = (setup_user_context $name) 
      let curr_value = ($context | get -o $key) 
      if $curr_value == null {
        _print $"🛑 invalid ($key) in setup " 
        exit 1
      }
      if $curr_value == $value {
        _print $"🛑 ($key) ($value) already set " 
        exit 1
      }
      # if $context != null and ( $context.infra | path exists) { return $context.infra } 
      let new_context = ($context | update $key $value) 
      setup_save_context  $new_context
    },
    "i" | "install" => { 
      install_config $reset --context
    },
    _ => { 
        invalid_task "context" ($task | default "") --end
    },
  }
  end_run $" create ($task) "
}