#!/usr/bin/env bash

# A task receives exactly the secrets it lists, only while it runs, and mise redacts them.

mkdir -p "$HOME/bin"
printf '#!/usr/bin/env bash\nexec python3 "%s" "$@"\n' "$TEST_ROOT/helpers/scripts/fnox_stub.py" >"$HOME/bin/fnox"
chmod +x "$HOME/bin/fnox"
export PATH="$HOME/bin:$PATH"
export FNOX_STUB_LOG="$PWD/fnox-calls.jsonl"
export FNOX_AGE_KEY=ambient-age SIGNING_KEY=ambient-sign

cat >mise.toml <<'TOML'
[secrets.fnox]
profile = "prod"

[env]
VAULT_ADDR = "https://vault.example"

[tasks.build]
run = '''
printf %s "${DEPLOY_KEY-unset}" >build.out
printf %s "${FNOX_AGE_KEY-unset}" >build-age.out
'''

[tasks.deploy]
depends = ["build"]
secrets = ["DEPLOY_KEY", "DATABASE_URL", "PEM_KEY"]
env = { TASK_ONLY = "1" }
run = '''
printf %s "$DEPLOY_KEY" >deploy.out
printf %s "${SIGNING_KEY-unset}" >signing.out
printf %s "${FNOX_AGE_KEY-unset}" >age.out
printf %s "$__MISE_SECRET_KEYS" >marker.out
echo "key=$DEPLOY_KEY"
echo "$PEM_KEY"
'''

[tasks.a]
secrets = ["DATABASE_URL"]
run = "true"

[tasks.b]
secrets = ["DATABASE_URL"]
run = "true"
TOML

# output is redacted, and the values reach only the task that listed them
assert_contains "mise run deploy </dev/null" "key=[redacted]"
assert_not_contains "mise run deploy </dev/null 2>&1" "s3cr3t"
assert_not_contains "mise run deploy </dev/null 2>&1" "Zm9v"
assert "cat build.out" "unset"
assert "cat deploy.out" "deploy-s3cr3t-0001"
assert "cat signing.out" "unset"
assert "cat age.out" "unset"
assert "cat build-age.out" "ambient-age"
assert "cat marker.out" "DATABASE_URL,DEPLOY_KEY,PEM_KEY"

# one fnox call with the sorted keys, and nothing it should not see
rm -f fnox-calls.jsonl
mise run deploy </dev/null >/dev/null 2>&1
assert "jq -s '[.[]|select(.argv|index(\"--keys\"))]|length' fnox-calls.jsonl" "1"
assert "jq -c 'select(.argv|index(\"--keys\"))|.argv' fnox-calls.jsonl" '["-P","prod","--non-interactive","--no-daemon","env","--json","--for","exec","--keys","DATABASE_URL,DEPLOY_KEY,PEM_KEY"]'
assert "jq -e 'select(.argv|index(\"--keys\"))|(.env_keys|index(\"VAULT_ADDR\")) != null and (.env_keys|index(\"TASK_ONLY\")) == null and ([.env_keys[]|select(startswith(\"__MISE_\"))]|length) == 0' fnox-calls.jsonl"
assert "jq -c 'select(.argv|index(\"--keys\"))|.leaked' fnox-calls.jsonl" "[]"
assert "jq -r 'select(.argv|index(\"--keys\"))|.cwd' fnox-calls.jsonl" "$(pwd -P)"

# two tasks that list the same key cause one batch
rm -f fnox-calls.jsonl
mise run a ::: b </dev/null >/dev/null 2>&1
assert "jq -s '[.[]|select(.argv|index(\"--keys\"))]|length' fnox-calls.jsonl" "1"

# profile and location
rm -f fnox-calls.jsonl
mkdir -p sub
(cd sub && mise run a </dev/null >/dev/null 2>&1)
assert "jq -r 'select(.argv|index(\"--keys\"))|.cwd' fnox-calls.jsonl" "$(pwd -P)"
cat >mise.local.toml <<'TOML'
[secrets.fnox]
profile = "me"
TOML
rm -f fnox-calls.jsonl
mise run a </dev/null >/dev/null 2>&1
assert "jq -r 'select(.argv|index(\"--keys\"))|.argv[1]' fnox-calls.jsonl" "me"
rm mise.local.toml

# file tasks, and an overlay that clears the list
mkdir -p mise-tasks
cat >mise-tasks/ft <<'SH'
#!/usr/bin/env bash
#MISE secrets=["DEPLOY_KEY"]
printf %s "${DEPLOY_KEY-unset}" >ft.out
SH
chmod +x mise-tasks/ft
mise run ft </dev/null >/dev/null 2>&1
assert "cat ft.out" "deploy-s3cr3t-0001"
cat >>mise.toml <<'TOML'

[tasks.ft]
secrets = []
TOML
mise run ft </dev/null >/dev/null 2>&1
assert "cat ft.out" "unset"

# values never reach mise's own output
assert_not_contains "mise env --json 2>&1" "s3cr3t"
assert_not_contains "mise hook-env -s bash 2>&1" "s3cr3t"

# the global raw setting and --raw cannot take redaction away
assert_contains "MISE_RAW=1 mise run deploy </dev/null | cat" "key=[redacted]"
assert_contains "mise run --raw deploy </dev/null 2>&1 | cat" "[redacted]"
assert_contains "mise run --raw deploy </dev/null 2>&1 | cat" "ignores --raw"

# a granted key that shares its name with an inherited secret survives the sandbox filter
cat >mise.toml <<'TOML'
[secrets.fnox]

[tasks.wild]
secrets = ["DEPLOY_KEY"]
allow_env = ["*"]
run = '''
printf %s "${DEPLOY_KEY-unset}" >wild.out
printf %s "${FNOX_AGE_KEY-unset}${SIGNING_KEY-unset}" >wild-ambient.out
'''
TOML
mise run wild </dev/null >/dev/null 2>&1
assert "cat wild.out" "deploy-s3cr3t-0001"
assert "cat wild-ambient.out" "unsetunset"
