#!/usr/bin/env bash

# auto_update moves an installed tool forward; it never installs one. A tool
# that is declared but missing, lazy or not, is left to the normal install paths
# (a lazy tool's first run, `mise install`), whichever updater checks it: a
# shell prompt (`mise hook-env`) or the tool-update service. The dummy backend
# offers 1.0.0, 1.1.0, and 2.0.0. `latest` matters: a prompt resolves offline,
# and a fuzzy version with nothing installed drops out before any update.

export MISE_STATE_DIR="$PWD/state"
mise uninstall dummy --all

reset_checks() {
  find "$MISE_STATE_DIR/tool-update" -type f ! -name '*.*' -delete 2>/dev/null || true
}

prompt() {
  reset_checks
  mise hook-env --shell bash --force >/dev/null 2>hook-env.err
  assert_empty "cat hook-env.err"
}

# The prompt never waits, so an update it started lands later: watch for one
# rather than sleeping a fixed time a slow machine could outlast.
assert_stays_missing() {
  for _ in {1..50}; do
    [[ -z "$(mise ls --installed dummy)" ]] || break
    sleep 0.1
  done
  assert_empty "mise ls --installed dummy"
}

# A prompt claims a tool's check, writing its marker (the undotted file), before
# it starts an update. No marker means no process or version lookup started,
# which the upgrade dropping a missing tool on its own would hide.
markers="find '$MISE_STATE_DIR/tool-update' -type f ! -name '*.*' ! -name prompt-next-check"

# A lazy tool nobody has run yet stays missing at a prompt.
printf '[tools]\ndummy = { version = "latest", lazy = true, auto_update = true }\n' >"$MISE_CONFIG_DIR/config.toml"
prompt
assert_empty "$markers"
assert_stays_missing

# So does a missing tool without lazy.
printf '[tools]\ndummy = { version = "latest", auto_update = true }\n' >"$MISE_CONFIG_DIR/config.toml"
prompt
assert_empty "$markers"
assert_stays_missing

# And one declared in system config, which counts as global for auto_update.
rm "$MISE_CONFIG_DIR/config.toml"
printf '[tools]\ndummy = { version = "latest", lazy = true, auto_update = true }\n' >"$MISE_SYSTEM_DIR/config.toml"
prompt
assert_empty "$markers"
assert_stays_missing

# A tool-update service pass leaves it missing too.
reset_checks
assert_succeed "mise __tool-update --due"
assert_stays_missing

# Once the tool is installed, the prompt updates it as before.
mise install dummy@1.0.0
prompt
assert_not_empty "$markers"
for _ in {1..300}; do
  mise ls --installed dummy | grep -q 2.0.0 && break
  sleep 0.1
done
assert_contains "mise ls --installed dummy" "2.0.0"
