#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
cd "$ROOT_DIR"

SANDBOX="$ROOT_DIR/sandbox/local-git-encrypted-collab"
REMOTE="$SANDBOX/remote.git"
USER1="$SANDBOX/user1"
USER2="$SANDBOX/user2"
USER1_HOME="$SANDBOX/user1-rho-home"
USER2_HOME="$SANDBOX/user2-rho-home"
USER1_ID="rho://id/github/rho-user1"
USER2_ID="rho://id/github/rho-user2"
REQUEST_BRANCH="rho-user2/encrypted-request"
RELEASE_BRANCH="rho-user1/encrypted-result"
REQUEST_PATH="rho/messages/inbox/id/github/rho-user1/request.yaml"
RESULT_PATH="rho/messages/inbox/id/github/rho-user2/result.yaml"

setup_git_user() {
  local repo="$1"
  local name="$2"
  local email="$3"
  git -C "$repo" config user.name "$name"
  git -C "$repo" config user.email "$email"
  git -C "$repo" config commit.gpgsign false
}

assert_clean() {
  local repo="$1"
  if ! git -C "$repo" diff --quiet || ! git -C "$repo" diff --cached --quiet; then
    echo "repo is unexpectedly dirty: $repo" >&2
    git -C "$repo" status --short >&2
    exit 1
  fi
}

rm -rf "$SANDBOX"
mkdir -p "$SANDBOX"

git init --bare "$REMOTE" >/dev/null

RHO_HOME="$USER1_HOME" ./rho id init \
  --github rho-user1 \
  --display-name "Rho User One" \
  --generate-ssh-key >/dev/null
RHO_HOME="$USER2_HOME" ./rho id init \
  --github rho-user2 \
  --display-name "Rho User Two" \
  --generate-ssh-key >/dev/null
RHO_HOME="$USER1_HOME" ./rho id export \
  --identity "$USER1_ID" \
  --out "$SANDBOX/rho-user1-public.yaml" >/dev/null
RHO_HOME="$USER2_HOME" ./rho id export \
  --identity "$USER2_ID" \
  --out "$SANDBOX/rho-user2-public.yaml" >/dev/null
RHO_HOME="$USER1_HOME" ./rho id import "$SANDBOX/rho-user2-public.yaml" >/dev/null
RHO_HOME="$USER2_HOME" ./rho id import "$SANDBOX/rho-user1-public.yaml" >/dev/null

git clone "$REMOTE" "$USER1" >/dev/null
setup_git_user "$USER1" "Rho User One" "user1@example.test"
git -C "$USER1" switch -c main >/dev/null

./rho repo init \
  --root "$USER1" \
  --repo-id rho://repo/local/encrypted-collab \
  --owner "$USER1_ID" >/dev/null
RHO_HOME="$USER1_HOME" ./rho id export \
  --identity "$USER1_ID" \
  --out "$USER1/rho/participants/rho-user1.yaml" >/dev/null
RHO_HOME="$USER2_HOME" ./rho id export \
  --identity "$USER2_ID" \
  --out "$USER1/rho/participants/rho-user2.yaml" >/dev/null
cat > "$USER1/rho/membership.yaml" <<EOF
version: 1
members:
  - identity: $USER1_ID
    role: owner
  - identity: $USER2_ID
    role: collaborator
EOF

RHO_HOME="$USER1_HOME" ./rho repo protect-path \
  "rho/messages/inbox/id/github/rho-user1/**" \
  --root "$USER1" \
  --rho-bin "$ROOT_DIR/rho" \
  --recipient "$USER1_ID" >/dev/null
RHO_HOME="$USER1_HOME" ./rho repo protect-path \
  "rho/messages/inbox/id/github/rho-user2/**" \
  --root "$USER1" \
  --rho-bin "$ROOT_DIR/rho" \
  --recipient "$USER2_ID" >/dev/null

grep -Fq "rho/messages/inbox/id/github/rho-user1/**" "$USER1/rho/policy/permissions.yaml"
grep -Fq "rho/messages/inbox/id/github/rho-user2/**" "$USER1/rho/policy/permissions.yaml"
grep -q "encryption: age-recipient-envelope" "$USER1/rho/policy/crypto.yaml"

RHO_HOME="$USER1_HOME" ./rho repo sign-governance --root "$USER1" >/dev/null
git -C "$USER1" add .gitattributes .gitignore rho rho.yaml
git -C "$USER1" commit -m "Initialize encrypted rho collaboration repo" >/dev/null
git -C "$USER1" push -u origin main >/dev/null
git -C "$REMOTE" symbolic-ref HEAD refs/heads/main
RHO_HOME="$USER1_HOME" ./rho repo doctor --root "$USER1" >/dev/null

git clone "$REMOTE" "$USER2" >/dev/null
setup_git_user "$USER2" "Rho User Two" "user2@example.test"
RHO_HOME="$USER2_HOME" ./rho repo install-filters \
  --root "$USER2" \
  --rho-bin "$ROOT_DIR/rho" >/dev/null
assert_clean "$USER2"
git -C "$USER2" switch -c "$REQUEST_BRANCH" >/dev/null

mkdir -p "$USER2/$(dirname "$REQUEST_PATH")"
cat > "$USER2/$REQUEST_PATH" <<EOF
version: 1
request:
  id: req-encrypted-collab
  from: $USER2_ID
  to: $USER1_ID
  task: sum private prices
  secret_value: 1113.03
EOF

RHO_HOME="$USER2_HOME" git -C "$USER2" add "$REQUEST_PATH"
git -C "$USER2" show ":$REQUEST_PATH" > "$SANDBOX/request-index.yaml"
grep -q "kind: rho_recipient_envelope" "$SANDBOX/request-index.yaml"
grep -q "$USER1_ID" "$SANDBOX/request-index.yaml"
if grep -q "1113.03" "$SANDBOX/request-index.yaml"; then
  echo "request index blob leaked plaintext" >&2
  exit 1
fi
grep -q "1113.03" "$USER2/$REQUEST_PATH"
git -C "$USER2" commit -m "Request encrypted private analysis" >/dev/null
git -C "$USER2" push -u origin "$REQUEST_BRANCH" >/dev/null

git -C "$USER1" fetch origin "$REQUEST_BRANCH:$REQUEST_BRANCH" >/dev/null
git -C "$USER1" worktree add "$SANDBOX/user1-review" "$REQUEST_BRANCH" >/dev/null
setup_git_user "$SANDBOX/user1-review" "Rho User One" "user1@example.test"
grep -q "1113.03" "$SANDBOX/user1-review/$REQUEST_PATH"
git -C "$SANDBOX/user1-review" show "HEAD:$REQUEST_PATH" > "$SANDBOX/request-commit.yaml"
grep -q "kind: rho_recipient_envelope" "$SANDBOX/request-commit.yaml"
if grep -q "1113.03" "$SANDBOX/request-commit.yaml"; then
  echo "request commit blob leaked plaintext" >&2
  exit 1
fi
RHO_HOME="$USER1_HOME" ./rho repo doctor --root "$SANDBOX/user1-review" >/dev/null

git -C "$USER1" worktree add -b "$RELEASE_BRANCH" "$SANDBOX/user1-release" main >/dev/null
setup_git_user "$SANDBOX/user1-release" "Rho User One" "user1@example.test"
mkdir -p "$SANDBOX/user1-release/$(dirname "$RESULT_PATH")"
cat > "$SANDBOX/user1-release/$RESULT_PATH" <<EOF
version: 1
result:
  request_id: req-encrypted-collab
  from: $USER1_ID
  to: $USER2_ID
  total: 1113.03
  note: result released only to rho-user2
EOF

RHO_HOME="$USER1_HOME" git -C "$SANDBOX/user1-release" add "$RESULT_PATH"
git -C "$SANDBOX/user1-release" show ":$RESULT_PATH" > "$SANDBOX/result-index.yaml"
grep -q "kind: rho_recipient_envelope" "$SANDBOX/result-index.yaml"
grep -q "$USER2_ID" "$SANDBOX/result-index.yaml"
if grep -q "1113.03" "$SANDBOX/result-index.yaml"; then
  echo "result index blob leaked plaintext" >&2
  exit 1
fi
git -C "$SANDBOX/user1-release" commit -m "Release encrypted private result" >/dev/null
git -C "$SANDBOX/user1-release" push -u origin "$RELEASE_BRANCH" >/dev/null
RHO_HOME="$USER1_HOME" ./rho repo doctor --root "$SANDBOX/user1-release" >/dev/null

git -C "$USER2" fetch origin "$RELEASE_BRANCH:$RELEASE_BRANCH" >/dev/null
git -C "$USER2" worktree add "$SANDBOX/user2-review" "$RELEASE_BRANCH" >/dev/null
setup_git_user "$SANDBOX/user2-review" "Rho User Two" "user2@example.test"
grep -q "1113.03" "$SANDBOX/user2-review/$RESULT_PATH"
git -C "$SANDBOX/user2-review" show "HEAD:$RESULT_PATH" > "$SANDBOX/result-commit.yaml"
grep -q "kind: rho_recipient_envelope" "$SANDBOX/result-commit.yaml"
if grep -q "1113.03" "$SANDBOX/result-commit.yaml"; then
  echo "result commit blob leaked plaintext" >&2
  exit 1
fi
RHO_HOME="$USER2_HOME" ./rho repo doctor --root "$SANDBOX/user2-review" >/dev/null

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" \
  -path "*/.git" -prune -o \
  -path "*/remote.git" -prune -o \
  -maxdepth 7 -type f -print | sort
echo "local git encrypted collaboration e2e passed"
