#!/usr/bin/env bash
# Re-tracking a path whose exclusions another machine published keeps
# them: the baseline is captured under the effective selection, not
# under this machine's declaration alone.
require_cmd git
export MISE_HISTORY_NOTIFY=false
origin="$PWD/retrack-origin.git"
git init -q --bare -b main "$origin"
mkdir -p ~/.codex/sessions
echo 'model = "x"' >~/.codex/config.toml
echo 'a transcript' >~/.codex/sessions/session.json
cat >"$MISE_CONFIG_DIR/config.toml" <<'TOML'
[dotfiles]
"~/.codex" = { mode = "track", exclude = ["sessions"], include = ["config.toml"] }
TOML
assert_succeed 'mise dot save'
assert_succeed "mise dot origin set file://$origin --sync manual --yes"
assert_succeed 'mise dot sync'
assert_fail "git --git-dir=$origin cat-file -e main:home/.codex/sessions/session.json"

# a second machine enrolls from the same origin and declares the path
# without repeating the exclusion
second="$(dirname "$HOME")/retrack-machine"
mkdir -p "$second/.config/mise" "$second/.codex/sessions"
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 bootstrap --adopt file://$origin --yes"
echo 'its own transcript' >"$second/.codex/sessions/session.json"
echo 'model = "y"' >"$second/.codex/config.toml"

# re-tracking captures under the published exclusion, and keeps it in
# the manifest rather than replacing the reconciled entry with the bare
# local declaration
assert_contains "b dot track --dry-run $second/.codex" "~/.codex: 1 file"
assert_contains "b dot track --dry-run $second/.codex" "exclude (~/.codex): sessions"
assert_contains "b dot track --dry-run $second/.codex" "include (~/.codex): config.toml"
assert_succeed "b dot track $second/.codex"
repository="$second/.local/state/mise/history/repo.git"
assert_contains "git --git-dir=$repository show HEAD:.mise-history/manifest.json" 'sessions'
assert_succeed "git --git-dir=$repository cat-file -e HEAD:home/.codex/config.toml"
assert_fail "git --git-dir=$repository cat-file -e HEAD:home/.codex/sessions/session.json"
# an include list survives the same way, and losing it would be worse:
# the entry would widen to its whole tree
cat >"$MISE_CONFIG_DIR/config.toml" <<'TOML'
[dotfiles]
"~/.codex" = { mode = "track", include = ["config.toml"] }
TOML
echo 'picked' >~/.codex/config.toml
echo 'not picked' >~/.codex/cache.db
assert_succeed 'mise dot save'
assert_succeed 'mise dot sync'
assert_succeed 'b dot sync --fetch-only'
# this machine edited the same file, so take the published version: the
# point here is the selection that travels with it, not the merge
assert_succeed 'b dot pull --take-remote-all --yes'
echo 'its own cache' >"$second/.codex/cache.db"
assert_succeed "b dot track $second/.codex"
assert_contains "git --git-dir=$repository show HEAD:.mise-history/manifest.json" 'config.toml'
assert_fail "git --git-dir=$repository cat-file -e HEAD:home/.codex/cache.db"

# still true on the next ordinary save, and nothing published it
echo 'edited' >"$second/.codex/config.toml"
assert_succeed 'b dot save'
assert_fail "git --git-dir=$repository cat-file -e HEAD:home/.codex/sessions/session.json"
assert_succeed 'b dot sync'
assert_fail "git --git-dir=$origin cat-file -e main:home/.codex/sessions/session.json"
