#!/usr/bin/env bash
# A tool named by `https://<user>:<token>@host/...` is logged as
# `https://[redacted]@host/...`. Its directories are named after the tool, and
# their paths reach logs, errors and `PATH`, so they must not spell the
# credentials either.

mkdir -p ~/bin
cat >~/bin/cargo <<'EOF'
#!/usr/bin/env bash
while (($#)); do
  if [[ $1 == --git=* ]]; then
    echo "${1#--git=}" >>"$HOME/cargo-git.log"
  fi
  if [[ $1 == "--root" ]]; then
    echo "  Installing $2/bin/private-tool" >&2
    mkdir -p "$2/bin"
    printf '#!/bin/sh\necho private-tool\n' >"$2/bin/private-tool"
    chmod +x "$2/bin/private-tool"
    exit 0
  fi
  shift
done
EOF
chmod u+x ~/bin/cargo
export PATH="$HOME/bin:$PATH"
export MISE_CARGO_BINSTALL=0
export MISE_OFFLINE=1

token=0123456789abcdef0123456789abcdef01234567
tool="cargo:https://ci-bot:$token@git.example.com/acme/private-tool.git"
dir="cargo-https-git-example-com-acme-private-tool-git"

# A directory named after the spelling with the credentials in it is removed
# once the tool is installed under its own name, with the links into it.
named="cargo-https-ci-bot-$token-git-example-com-acme-private-tool-git"
mkdir -p "$MISE_DATA_DIR/installs/$named/tag-1.0.0/bin" "$MISE_DATA_DIR/shims"
touch "$MISE_DATA_DIR/installs/$named/tag-1.0.0/bin/private-tool"
ln -s ./tag-1.0.0 "$MISE_DATA_DIR/installs/$named/latest"
ln -s "$MISE_DATA_DIR/installs/$named/tag-1.0.0/bin/private-tool" "$MISE_DATA_DIR/shims/private-tool-named"

assert_not_contains "mise install --verbose '$tool@tag:1.0.0' 2>&1" "$token"
assert_directory_not_exists "$MISE_DATA_DIR/installs/$named"
assert_fail "test -L '$MISE_DATA_DIR/shims/private-tool-named'"
assert "mise x '$tool@tag:1.0.0' -- private-tool" "private-tool"
assert "mise where '$tool@tag:1.0.0'" "$MISE_DATA_DIR/installs/$dir/tag-1.0.0"
assert_empty "find '$MISE_DATA_DIR' '$MISE_CACHE_DIR' '$MISE_STATE_DIR' -name '*$token*'"

# Install state records the tool without its credentials, and the configured
# spelling still finds it, once.
manifests="$MISE_DATA_DIR/installs/.mise-installs.toml $MISE_DATA_DIR/installs/$dir/.mise.backend.toml"
assert_not_contains "cat $manifests" "$token"
assert_contains "cat $manifests" "cargo:https://git.example.com/acme/private-tool.git"
cat >mise.toml <<EOF
[tools]
"$tool" = "tag:1.0.0"
EOF
assert "mise ls --installed --json | jq 'keys | length'" "1"

# A manifest that holds the credentials is read without them, and rewritten.
printf 'short = "%s"\nfull = "%s"\n' "$tool" "$tool" >"$MISE_DATA_DIR/installs/$dir/.mise.backend.toml"
assert "mise where '$tool@tag:1.0.0'" "$MISE_DATA_DIR/installs/$dir/tag-1.0.0"
assert_not_contains "cat $MISE_DATA_DIR/installs/$dir/.mise.backend.toml" "$token"
rm mise.toml

# The record is credential-free, but a forced reinstall of the credentialed
# spelling still builds from the URL with its credentials.
rm -f ~/cargo-git.log
assert_succeed "mise install -f '$tool@tag:1.0.0'"
assert_contains "cat ~/cargo-git.log" "https://ci-bot:$token@git.example.com/acme/private-tool.git"

mkdir -p "$MISE_CACHE_DIR/$dir"
assert_succeed "mise cache clear '$tool'"
assert_directory_not_exists "$MISE_CACHE_DIR/$dir"

# `mise lock` prints the tool and its backend, in text and in --json, and
# records them without the credentials.
cat >mise.toml <<EOF
[tools]
"$tool" = "tag:1.0.0"
EOF
touch mise.lock
assert_not_contains "mise lock --platform linux-x64 2>&1" "$token"
: >mise.lock
assert_not_contains "mise lock --platform linux-x64 --json 2>&1" "$token"
: >mise.lock
assert_contains "mise lock --platform linux-x64 --json 2>&1" "git.example.com/acme/private-tool.git"
assert_not_contains "mise lock --platform linux-x64 --dry-run 2>&1" "$token"
assert_not_contains "cat mise.lock" "$token"
assert_contains "cat mise.lock" "cargo:https://git.example.com/acme/private-tool.git"
rm mise.toml mise.lock

# A token in the query string stays out of names and records the same way.
qtool="cargo:https://git.example.com/acme/private-tool.git?private_token=$token"
assert_succeed "mise install '$qtool@tag:1.0.0'"
assert "mise where '$qtool@tag:1.0.0'" "$MISE_DATA_DIR/installs/$dir/tag-1.0.0"
assert_empty "find '$MISE_DATA_DIR' '$MISE_CACHE_DIR' '$MISE_STATE_DIR' -name '*$token*'"
assert_not_contains "cat $MISE_DATA_DIR/installs/.mise-installs.toml $MISE_DATA_DIR/installs/$dir/.mise.backend.toml" "$token"
