#!/usr/bin/env bash
# shellcheck disable=SC2016
# Narrowing a tracked directory with `include` stops managing a file; it
# is not a deletion for the other machines to replay. A file deleted
# while it is still selected still is.
require_cmd git
export MISE_HISTORY_NOTIFY=false
origin="$PWD/selection-sync-origin.git"
git init -q --bare -b main "$origin"
mkdir -p ~/.sample/nested
echo keep >~/.sample/keep
echo leave >~/.sample/leave
echo nested >~/.sample/nested/leave
cat >"$MISE_CONFIG_DIR/config.toml" <<'TOML'
[dotfiles]
"~/.sample" = { mode = "track" }
TOML
assert_succeed 'mise dot save'
assert_succeed "mise dot origin set file://$origin --sync manual --yes"
assert_succeed 'mise dot sync'

second="$(dirname "$HOME")/second"
mkdir -p "$second/.config/mise" "$second/.local/state/mise/history" "$second/.sample/nested"
git clone -q --bare "$origin" "$second/.local/state/mise/history/repo.git"
echo keep >"$second/.sample/keep"
echo leave >"$second/.sample/leave"
echo nested >"$second/.sample/nested/leave"
cat >"$second/.config/mise/config.toml" <<'TOML'
[dotfiles]
"~/.sample" = { mode = "track" }
TOML
b() {
  (
    cd "$second" || exit
    env HOME="$second" XDG_CONFIG_HOME="$second/.config" MISE_CONFIG_DIR="$second/.config/mise" \
      MISE_STATE_DIR="$second/.local/state/mise" MISE_DATA_DIR="$second/.local/share/mise" \
      MISE_CACHE_DIR="$second/.cache/mise" MISE_TRUSTED_CONFIG_PATHS="$second" \
      MISE_HISTORY_NOTIFY=false mise "$@"
  )
}
export second
export -f b
assert_succeed "b dot origin set file://$origin --sync manual --yes"
assert_succeed 'b dot sync --fetch-only'
assert_succeed 'b dot pull --yes'

# machine one narrows its selection to ~/.sample/keep
cat >"$MISE_CONFIG_DIR/config.toml" <<'TOML'
[dotfiles]
"~/.sample" = { mode = "track", include = ["keep"] }
TOML
assert_succeed 'mise dot save'
assert "cat ~/.sample/leave" 'leave'
assert_succeed 'mise dot sync'

# machine two keeps its copy: narrowing selection is not a deletion —
# including the copy whose kind it cannot even read. Asked permissively
# ("might this path matter"), a name-only include list prunes nothing, so
# an unreadable path looks managed although no pattern selects it, and the
# narrowing deletes it. Synchronization asks the strict question instead.
# (As root, chmod does not restrict and the path is simply read as the
# file it is; the assertions hold either way.)
assert_succeed 'b dot sync --fetch-only'
# planning is where the question is asked, so that is where the copy is
# unreadable. (Restored before the pull writes: a tracked subtree this
# machine cannot read makes the pull's own protective save disagree with
# the plan it just made, which is a different refusal and not this one.)
chmod 000 "$second/.sample/nested"
assert_not_contains 'b dot pull --dry-run' 'home/.sample/leave'
assert_not_contains 'b dot pull --dry-run' 'home/.sample/nested/leave'
chmod 755 "$second/.sample/nested"
assert_succeed 'b dot pull --yes'
assert "cat $second/.sample/leave" 'leave'
assert "cat $second/.sample/nested/leave" 'nested'

# a file deleted while it is still selected is still propagated
rm ~/.sample/keep
assert_succeed 'mise dot save'
assert_succeed 'mise dot sync'
assert_succeed 'b dot sync --fetch-only'
assert_succeed 'b dot pull --yes'
assert_fail "test -e $second/.sample/keep"
assert "cat $second/.sample/leave" 'leave'
