#!/usr/bin/env bash
# a merge = "missing" template resolves secret() only for the keys the target
# lacks, so a key that is already set never asks for its secret again.
mkdir -p templates
cat <<'TOML' >templates/private.toml
[env]
MISE_GITHUB_TOKEN = "{{ secret(name='github_token') }}"
NPM_TOKEN = "{{ secret(name='npm_token') }}"
TOML
cat <<'TOML' >mise.toml
[bootstrap.secrets]
github_token = "SEED_GITHUB_TOKEN"
npm_token = "SEED_NPM_TOKEN"

[dotfiles]
"~/.config/mise/conf.d/private.local.toml/seed" = { source = "templates/private.toml", template = "tera", merge = "missing", permissions = "0600" }
TOML
target="$HOME/.config/mise/conf.d/private.local.toml"
unset SEED_GITHUB_TOKEN SEED_NPM_TOKEN

# status and diff report the missing keys without reading or prompting for a secret
assert_contains "mise dot status" "missing"
assert_contains "mise dot diff" "‹secret:github_token›"

# a secret that is unavailable fails closed and leaves no file behind
assert_fail_contains "mise dot apply --yes" "required bootstrap secrets are unavailable"
assert_fail "test -e $target"
assert_fail_contains "SEED_GITHUB_TOKEN=gh-1 mise dot apply --yes" "npm_token"
assert_fail "test -e $target"

# a missing target is created from the secrets, with the declared mode
assert_succeed "SEED_GITHUB_TOKEN=gh-1 SEED_NPM_TOKEN=npm-1 mise dot apply --yes"
assert_contains "cat $target" 'MISE_GITHUB_TOKEN = "gh-1"'
assert_contains "cat $target" 'NPM_TOKEN = "npm-1"'
assert "stat -c %a $target" "600"
assert_contains "mise dot status --verbose" "applied"

# a key that is set keeps its value and asks for nothing
sed -i 's/npm-1/npm-edited/' "$target"
assert_succeed "mise dot apply --yes"
assert_contains "cat $target" 'NPM_TOKEN = "npm-edited"'
assert_contains "cat $target" 'MISE_GITHUB_TOKEN = "gh-1"'

# a key added to the source asks only for its own secret
cat <<'TOML' >>templates/private.toml
PYPI_TOKEN = "{{ secret(name='pypi_token') }}"
TOML
cat <<'TOML' >mise.toml
[bootstrap.secrets]
github_token = "SEED_GITHUB_TOKEN"
npm_token = "SEED_NPM_TOKEN"
pypi_token = "SEED_PYPI_TOKEN"

[dotfiles]
"~/.config/mise/conf.d/private.local.toml/seed" = { source = "templates/private.toml", template = "tera", merge = "missing", permissions = "0600" }
TOML
assert_fail_contains "mise dot apply --yes" "pypi_token"
assert_succeed "SEED_PYPI_TOKEN=pypi-1 mise dot apply --yes"
assert_contains "cat $target" 'PYPI_TOKEN = "pypi-1"'
assert_contains "cat $target" 'NPM_TOKEN = "npm-edited"'

# a diff never shows a value
printf '[env]\nMISE_GITHUB_TOKEN = "gh-1"\n' >"$target"
assert_not_contains "SEED_NPM_TOKEN=npm-secret SEED_PYPI_TOKEN=pypi-secret mise dot diff" "npm-secret"

# a secret that is not declared is an error, even for a key that is set
cat <<'TOML' >templates/private.toml
[env]
MISE_GITHUB_TOKEN = "{{ secret(name='undeclared') }}"
TOML
assert_fail_contains "mise dot apply --yes" "undeclared"

# an enforced merge cannot use secret()
cat <<'TOML' >mise.toml
[bootstrap.secrets]
github_token = "SEED_GITHUB_TOKEN"

[dotfiles]
"~/.config/mise/conf.d/private.local.toml/seed" = { source = "templates/private.toml", template = "tera", merge = true }
TOML
assert_fail_contains "SEED_GITHUB_TOKEN=gh-1 mise dot apply --yes" "secret"

# a filter that changes the placeholder is refused instead of written as the
# secret, and filling in a secret does not render the template again
rm -f "$target" "$HOME/exec-count"
cat <<'TOML' >templates/private.toml
[env]
TOKEN = "{{ secret(name='github_token') | upper }}"
TOML
cat <<'TOML' >mise.toml
[bootstrap.secrets]
github_token = "SEED_GITHUB_TOKEN"

[dotfiles]
"~/.config/mise/conf.d/private.local.toml/seed" = { source = "templates/private.toml", template = "tera", merge = "missing" }
TOML
assert_fail_contains "SEED_GITHUB_TOKEN=gh-1 mise dot apply --yes" "has to be inserted as it is"
assert_fail "test -e $target"
cat <<'TOML' >templates/private.toml
[env]
VALUE = "{{ exec(command='echo run >> $HOME/exec-count; echo v') }}"
TOML
assert_succeed "mise dot apply --yes"
runs="$(wc -l <"$HOME/exec-count" | tr -d ' ')"
rm -f "$target" "$HOME/exec-count"
cat <<'TOML' >templates/private.toml
[env]
VALUE = "{{ exec(command='echo run >> $HOME/exec-count; echo v') }}"
TOKEN = "{{ secret(name='github_token') }}"
TOML
assert_succeed "SEED_GITHUB_TOKEN=gh-1 mise dot apply --yes"
assert_contains "cat $target" 'TOKEN = "gh-1"'
assert_contains "cat $target" 'VALUE = "v"'
assert "wc -l <$HOME/exec-count | tr -d ' '" "$runs"
