#!/usr/bin/env nu

# External Command Execution Helpers
# Provides safe command execution with error handling (no try-catch, use do-complete)
# Usage: use external.nu; run-cmd "nickel" ["typecheck", "file.ncl"]

export def run-cmd [cmd: string, args: list<string>]: nothing -> record<exit_code: int, stdout: string, stderr: string> {
  let result = do {
    ^$cmd ...$args
  } | complete

  $result
}

export def run-cmd-or-fail [cmd: string, args: list<string>, error_msg: string]: nothing -> string {
  let result = (run-cmd $cmd $args)

  if $result.exit_code != 0 {
    error make {
      msg: $"($error_msg): ($result.stderr)"
    }
  }

  $result.stdout
}

export def check-command-exists [cmd: string]: string -> bool {
  let result = do {
    which $cmd
  } | complete

  $result.exit_code == 0
}

export def assert-command-exists [cmd: string]: nothing -> nothing {
  if not (check-command-exists $cmd) {
    error make {
      msg: $"Required command not found: ($cmd)"
    }
  }
}

export def run-nickel-typecheck [path: string]: nothing -> nothing {
  assert-command-exists "nickel"

  let result = (run-cmd "nickel" ["typecheck", $path])

  if $result.exit_code != 0 {
    error make {
      msg: $"Nickel typecheck failed for ($path): ($result.stderr)"
    }
  }
}

export def run-nickel-export [path: string, format: string]: nothing -> string {
  assert-command-exists "nickel"

  (run-cmd-or-fail "nickel" ["export", "--format", $format, $path] $"Nickel export failed for ($path)")
}

export def run-yq-convert [input: string, output_format: string]: nothing -> string {
  assert-command-exists "yq"

  let result = do {
    echo $input | ^yq $"-P"
  } | complete

  if $result.exit_code != 0 {
    error make {
      msg: $"yq conversion failed: ($result.stderr)"
    }
  }

  $result.stdout
}

export def run-typedialog [backend: string, args: list<string>]: nothing -> record<exit_code: int, stdout: string, stderr: string> {
  assert-command-exists "typedialog"

  let cmd_args = [$backend] | append $args

  (run-cmd "typedialog" $cmd_args)
}

export def run-typedialog-or-fail [backend: string, args: list<string>, error_msg: string]: nothing -> nothing {
  let result = (run-typedialog $backend $args)

  if $result.exit_code != 0 {
    error make {
      msg: $"($error_msg): ($result.stderr)"
    }
  }
}

export def run-docker [args: list<string>]: nothing -> record<exit_code: int, stdout: string, stderr: string> {
  assert-command-exists "docker"

  (run-cmd "docker" $args)
}

export def run-kubectl [args: list<string>]: nothing -> record<exit_code: int, stdout: string, stderr: string> {
  assert-command-exists "kubectl"

  (run-cmd "kubectl" $args)
}

export def pipe-to-file [content: string, path: string]: string -> nothing {
  $content | save --force $path
}

export def file-exists [path: string]: string -> bool {
  ($path | path exists)
}

export def dir-exists [path: string]: string -> bool {
  ($path | path exists) and (($path | path type) == "dir")
}
