#!/usr/bin/env bash
#
# Enforce spec §3 rule 1: "No crate other than `df-store` may depend on `gix`.
# Add this to CI as a dependency check."
#
# The whole value of the RepoStore abstraction is that swapping in a jj-native
# backend later touches one crate. That guarantee is worth exactly as much as
# this check — the moment a second crate reaches for `gix`, the boundary is
# gone and nobody notices until the migration.

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
FAIL=0

echo "==> checking the df-store boundary"

# 1. Only df-store may declare gix as a dependency.
while IFS= read -r manifest; do
    crate="$(basename "$(dirname "$manifest")")"
    [[ "$crate" == "df-store" ]] && continue

    if grep -qE '^\s*gix\s*[=.]|^\s*gix\s*=\s*\{' "$manifest"; then
        echo "  FAIL: $crate declares a dependency on gix ($manifest)"
        FAIL=1
    fi
done < <(find "$ROOT/crates" -name Cargo.toml)

# 2. Only df-store may name gix in its source.
while IFS= read -r file; do
    case "$file" in
        "$ROOT"/crates/df-store/*) continue ;;
    esac
    if grep -nE '(^|[^A-Za-z_])gix::|extern crate gix' "$file" >/dev/null 2>&1; then
        echo "  FAIL: $(realpath --relative-to="$ROOT" "$file") references gix::"
        grep -nE '(^|[^A-Za-z_])gix::|extern crate gix' "$file" | head -3 | sed 's/^/         /'
        FAIL=1
    fi
done < <(find "$ROOT/crates" -name '*.rs')

# 3. RevId must stay opaque: nothing outside df-store may slice or measure it.
#    Spec §3 rule 2 — "do not parse it, do not assume it is 40 hex characters,
#    do not abbreviate it outside df-store."
while IFS= read -r file; do
    case "$file" in
        "$ROOT"/crates/df-store/*) continue ;;
    esac
    if grep -nE '\.as_str\(\)\s*\[|rev\s*\[\s*\.\.|\.rev\.as_str\(\)\[' "$file" >/dev/null 2>&1; then
        echo "  FAIL: $(realpath --relative-to="$ROOT" "$file") appears to slice a RevId"
        FAIL=1
    fi
done < <(find "$ROOT/crates" -name '*.rs')

if [[ $FAIL -eq 0 ]]; then
    echo "  ok — gix is confined to df-store, RevId is opaque"
else
    echo
    echo "The storage boundary exists so that moving to a jj-native backend is a"
    echo "swap of one implementation rather than a rewrite. Route what you need"
    echo "through the RepoStore trait instead."
    exit 1
fi
