#!/usr/bin/env bash
# A credential store under a tracked directory is dropped from every save;
# the save, the enrollment, and the status must say so rather than only
# `mise dot paths`, and a public key is not a credential store.
require_cmd git
repo="$MISE_STATE_DIR/history/repo.git"
mkdir -p ~/.config/fish/functions ~/.ssh
echo 'function hello; end' >~/.config/fish/functions/hello.fish
echo 'set -x API_TOKEN synthetic' >~/.config/fish/functions/secrets.fish
echo 'ssh-ed25519 AAAA synthetic' >~/.ssh/id_test.pub
echo 'synthetic private key' >~/.ssh/id_test
echo 'synthetic' >~/.ssh/client_secret.pub

# Tracking a directory reports what its baseline leaves out.
assert_contains 'mise dot track ~/.config/fish 2>&1' 'omitted: ~/.config/fish/functions/secrets.fish (credential store'
assert "git --git-dir=$repo show HEAD:home/.config/fish/functions/hello.fish" 'function hello; end'
assert_fail "git --git-dir=$repo cat-file -e HEAD:home/.config/fish/functions/secrets.fish"

# The guard matches by name alone: a public key is reported like the
# private key beside it (un-protecting is the user's call).
assert_contains 'mise dot track ~/.ssh 2>&1' 'omitted: ~/.ssh/id_test (credential store'
assert_contains 'mise dot track ~/.ssh 2>&1' 'omitted: ~/.ssh/id_test.pub (credential store'
assert_fail "git --git-dir=$repo cat-file -e HEAD:home/.ssh/id_test.pub"
assert_fail "git --git-dir=$repo cat-file -e HEAD:home/.ssh/id_test"
assert_fail "git --git-dir=$repo cat-file -e HEAD:home/.ssh/client_secret.pub"
assert_contains 'mise dot paths' 'omitted: ~/.ssh/client_secret.pub (credential store'

# A save reports every omission, even when nothing else changed.
assert_contains 'mise dot save 2>&1' 'omitted: ~/.config/fish/functions/secrets.fish (credential store'
assert_contains 'mise dot save 2>&1' 'omitted: ~/.ssh/id_test (credential store'
echo 'function hello; echo hi; end' >~/.config/fish/functions/hello.fish
assert_contains 'mise dot save 2>&1' 'secrets.fish'
assert "git --git-dir=$repo show HEAD:home/.config/fish/functions/hello.fish" 'function hello; echo hi; end'

# Status names the count in the table and in the history block.
assert_contains 'mise dot status' 'tracked (3 omitted)'
assert_contains 'mise dot status' '4 files omitted from capture (credential store)'
assert "mise dot status --json | jq -r '.history.omitted | length'" 4
assert "mise dot status --json | jq -r '.files[] | select(.target == \"~/.ssh\") | .omitted'" 3
assert_contains 'mise dot paths' 'omitted: ~/.ssh/id_test (credential store; encrypt the file before tracking it)'

# Tracking a credential file itself warns and points at --encrypt.
echo synthetic >~/.api-token
assert_contains 'mise dot track ~/.api-token 2>&1' '~/.api-token will be omitted from every save (credential store'
assert_contains 'mise dot track ~/.api-token 2>&1' 'mise dot track --encrypt'
assert_fail "git --git-dir=$repo cat-file -e HEAD:home/.api-token"

# A directory the guard would never test by name is not promised the
# protection a file of that name gets: its files are decided one by one.
mkdir -p ~/.app-secrets
echo 'client = "synthetic"' >~/.app-secrets/app.toml
assert_not_contains 'mise dot track ~/.app-secrets 2>&1' 'will be omitted from every save'
assert "git --git-dir=$repo show HEAD:home/.app-secrets/app.toml" 'client = "synthetic"'

# and a path with no kind yet is told what happens to it as a file, not
# promised an omission the directory it becomes would never get
assert_contains 'mise dot track ~/.secrets-later 2>&1' 'if it is created as a file, never as a directory'
mkdir -p ~/.secrets-later
echo 'kept = true' >~/.secrets-later/app.toml
assert_succeed 'mise dot save'
assert "git --git-dir=$repo show HEAD:home/.secrets-later/app.toml" 'kept = true'

# A symlinked home directory is a supported portable root. Its status
# rows must match omissions from the canonical paths used by the walk.
alias_home="$(dirname "$HOME")/alias-home"
ln -s "$HOME" "$alias_home"
assert "env HOME=$alias_home XDG_CONFIG_HOME=$alias_home/.config MISE_CONFIG_DIR=$alias_home/.config/mise mise dot status --json | jq -r '.files[] | select(.target == \"~/.ssh\") | .omitted'" 3
