#!/usr/bin/env bash

set -euo pipefail

unset MISE_CARGO_HOME MISE_RUSTUP_HOME
export MISE_OFFLINE=1
export MISE_ENV_CACHE=1

CONFIG_CARGO_HOME="$PWD/config-cargo"
CONFIG_RUSTUP_HOME="$PWD/config-rustup"
mkdir -p "$CONFIG_CARGO_HOME/bin" "$CONFIG_RUSTUP_HOME"
touch "$CONFIG_RUSTUP_HOME/settings.toml"

cat >"$CONFIG_CARGO_HOME/bin/cargo" <<'EOF'
#!/usr/bin/env bash
echo "cargo:$RUSTUP_TOOLCHAIN:$*"
EOF

cat >"$CONFIG_CARGO_HOME/bin/rustc" <<'EOF'
#!/usr/bin/env bash
echo "rustc ${RUSTUP_TOOLCHAIN:-unknown}"
EOF

cat >"$CONFIG_CARGO_HOME/bin/rustup" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

echo "$*" >>"$CARGO_HOME/rustup.log"

case "$1 $2" in
	"show profile")
		echo minimal
		;;
	"component list")
		echo rustfmt
		;;
	"toolchain install")
		mkdir -p "$RUSTUP_HOME/toolchains/$3"
		;;
	"toolchain uninstall")
		;;
	*)
		echo "unexpected rustup args: $*" >&2
		exit 1
		;;
esac
EOF

chmod +x "$CONFIG_CARGO_HOME/bin/cargo" "$CONFIG_CARGO_HOME/bin/rustc" "$CONFIG_CARGO_HOME/bin/rustup"

mkdir -p "$PWD/mbx/bin"
cat >"$PWD/mbx/bin/mbx" <<'EOF'
#!/usr/bin/env bash
printf 'mbx:%s\n' "$MBX_CARGO_SHIM_MODE"
exec cargo "$@"
EOF
chmod +x "$PWD/mbx/bin/mbx"

cat >mise.toml <<EOF
[env]
MISE_CARGO_HOME = "$CONFIG_CARGO_HOME"
MISE_RUSTUP_HOME = "$CONFIG_RUSTUP_HOME"
[tools]
rust = { version = "1.81.0", components = ["rustfmt"] }
[tasks.check]
run = "cargo check"
[tasks.unwrapped]
tools = { rust = { version = "1.81.0", mr_boxington = false } }
run = "cargo check"
EOF

mise use --tool-option mr_boxington=true rust@1.81.0 "mr-boxington@path:$PWD/mbx"
assert "mise config get tools.rust.mr_boxington" "true"
assert_contains "cat mise.toml" 'mr_boxington = true'
assert_contains "cat mise.toml" 'components = ["rustfmt"]'
assert "mise exec -- cargo check" "mbx:1
cargo:1.81.0:check"
assert "mise run check 2>/dev/null" "mbx:1
cargo:1.81.0:check"
assert_contains "mise hook-env -s bash --force" "$MISE_DATA_DIR/command-wrappers/bin"
assert "'$MISE_DATA_DIR/shims/cargo' check" "mbx:1
cargo:1.81.0:check"
(
  eval "$(mise activate bash --shims)"
  assert "cargo check" "mbx:1
cargo:1.81.0:check"
)

assert "mise exec 'rust[mr_boxington=false]@1.81.0' -- cargo check" "cargo:1.81.0:check"
assert "mise run unwrapped 2>/dev/null" "cargo:1.81.0:check"

# Safe mode ignores project-provided wrapping.
assert "MISE_CARGO_HOME='$CONFIG_CARGO_HOME' MISE_RUSTUP_HOME='$CONFIG_RUSTUP_HOME' MISE_SAFE=1 mise exec -- cargo check" "cargo:1.81.0:check"

# Project overrides turn off a global/parent default.
mkdir child
(
  cd child
  printf '[tools]\nrust = { version = "1.81.0", mr_boxington = false }\n' >mise.toml
  assert "mise exec -- cargo check" "cargo:1.81.0:check"
  assert "'$MISE_DATA_DIR/shims/cargo' check" "cargo:1.81.0:check"
  printf '[tools]\nrust = "1.81.0"\n' >mise.toml
  assert "mise exec -- cargo check" "cargo:1.81.0:check"
)

# Task and exec opt-ins work without a previously generated wrapper.
mise use --tool-option mr_boxington=false rust@1.81.0
mise reshim
assert_fail "test -e '$MISE_DATA_DIR/command-wrappers/bin/cargo'"
cat >>mise.toml <<'EOF'
[tasks.wrapped]
tools = { rust = { version = "1.81.0", mr_boxington = true } }
run = "cargo check"
EOF
assert "mise run wrapped 2>/dev/null" "mbx:1
cargo:1.81.0:check"
assert "mise run check 2>/dev/null" "cargo:1.81.0:check"
assert "mise run wrapped 2>/dev/null" "mbx:1
cargo:1.81.0:check"
mise reshim
assert "mise exec 'rust[mr_boxington=true]@1.81.0' -- cargo check" "mbx:1
cargo:1.81.0:check"

# Explicit wrappers take precedence.
cat >>mise.toml <<'EOF'
[wrappers.cargo]
command = "echo"
args = ["custom"]
EOF
assert "mise exec -- cargo check" "custom check"

# Missing dependencies produce actionable errors, not accidental PATH fallbacks.
cat >mise.toml <<EOF
[env]
MISE_CARGO_HOME = "$CONFIG_CARGO_HOME"
MISE_RUSTUP_HOME = "$CONFIG_RUSTUP_HOME"
[tools]
rust = { version = "1.81.0", mr_boxington = true }
EOF
assert_fail_contains "mise exec -- cargo check 2>&1" "requires mr-boxington in [tools]"
cat >>mise.toml <<'EOF'
[wrappers.cargo]
command = "echo"
args = ["custom"]
EOF
assert "mise exec -- cargo check" "custom check"

: >mise.toml
mise reshim
assert_fail "test -e '$MISE_DATA_DIR/command-wrappers/bin/cargo'"
