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

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

SANDBOX="$ROOT_DIR/sandbox/rho-auto-encrypt-policy"
REPO="$SANDBOX/repo"
USER1_ID="rho://id/github/rho-owner"
USER2_ID="rho://id/github/rho-writer"
USER3_ID="rho://id/github/rho-admin"
PROTECTED_PATH="rho/messages/inbox/id/github/rho-owner/request.yaml"

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

git -C "$REPO" init >/dev/null
git -C "$REPO" config user.name "Rho Auto Encrypt Test"
git -C "$REPO" config user.email "auto@example.test"
git -C "$REPO" config commit.gpgsign false

./rho repo init \
  --root "$REPO" \
  --repo-id rho://repo/local/auto-encrypt \
  --owner "$USER1_ID" >/dev/null

RHO_HOME="$SANDBOX/user1-rho-home" ./rho id init \
  --github rho-owner \
  --display-name "Rho Owner" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id init \
  --github rho-writer \
  --display-name "Rho Writer" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho id init \
  --github rho-admin \
  --display-name "Rho Admin" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user1-rho-home" ./rho id export \
  --identity "$USER1_ID" \
  --out "$REPO/rho/participants/rho-owner.yaml" >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id export \
  --identity "$USER2_ID" \
  --out "$REPO/rho/participants/rho-writer.yaml" >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho id export \
  --identity "$USER3_ID" \
  --out "$REPO/rho/participants/rho-admin.yaml" >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id import \
  "$REPO/rho/participants/rho-owner.yaml" >/dev/null

cat > "$REPO/rho/membership.yaml" <<EOF
version: 1
members:
  - identity: $USER1_ID
    role: owner
  - identity: $USER2_ID
    role: collaborator
  - identity: $USER3_ID
    role: owner
EOF

RHO_HOME="$SANDBOX/user2-rho-home" ./rho repo protect-path \
  "rho/messages/inbox/id/github/rho-owner/**" \
  --root "$REPO" \
  --rho-bin "$ROOT_DIR/rho" \
  --recipient "$USER1_ID" >/dev/null

grep -q "permissions:" "$REPO/rho/policy/permissions.yaml"
grep -q "encrypted_to:" "$REPO/rho/policy/permissions.yaml"
grep -q "$USER1_ID" "$REPO/rho/policy/permissions.yaml"
grep -q "encryption: age-recipient-envelope" "$REPO/rho/policy/crypto.yaml"
grep -q "transparent_git_filters: enabled" "$REPO/rho/policy/crypto.yaml"
grep -q "filter: rho-crypt" "$REPO/rho/policy/crypto.yaml"
if grep -q "protected_paths:" "$REPO/rho/policy/crypto.yaml"; then
  echo "crypto policy still owns protected paths" >&2
  exit 1
fi
grep -q "rho: 1" "$REPO/rho.yaml"
grep -Fq "rho/messages/inbox/id/github/rho-owner/** filter=rho-crypt" "$REPO/.gitattributes"
grep -Fq "# >>> rho generated encrypted path filters >>>" "$REPO/.gitattributes"
grep -Fq "# <<< rho generated encrypted path filters <<<" "$REPO/.gitattributes"
test "$(grep -Fc "rho/messages/inbox/id/github/rho-owner/** filter=rho-crypt" "$REPO/.gitattributes")" = "1"

RHO_HOME="$SANDBOX/user2-rho-home" ./rho repo install-filters \
  --root "$REPO" \
  --rho-bin "$ROOT_DIR/rho" >/dev/null
grep -Fq "# >>> rho generated encrypted path filters >>>" "$REPO/.gitattributes"
test "$(grep -Fc "rho/messages/inbox/id/github/rho-owner/** filter=rho-crypt" "$REPO/.gitattributes")" = "1"

mkdir -p "$REPO/rho/messages/inbox/id/github/rho-owner"
cat > "$REPO/$PROTECTED_PATH" <<EOF
version: 1
request:
  note: plaintext in worktree, encrypted in index
  value: 1113.03
EOF

RHO_HOME="$SANDBOX/user2-rho-home" git -C "$REPO" add .gitattributes rho
git -C "$REPO" show ":$PROTECTED_PATH" > "$SANDBOX/index-request.yaml"
grep -q "kind: rho_recipient_envelope" "$SANDBOX/index-request.yaml"
grep -q "$USER1_ID" "$SANDBOX/index-request.yaml"
grep -q "$USER2_ID" "$SANDBOX/index-request.yaml"
grep -q "$USER3_ID" "$SANDBOX/index-request.yaml"
grep -q "context:" "$SANDBOX/index-request.yaml"
grep -q "repo_id: rho://repo/local/auto-encrypt" "$SANDBOX/index-request.yaml"
grep -q "path: $PROTECTED_PATH" "$SANDBOX/index-request.yaml"
grep -q "purpose: rho.git_filter" "$SANDBOX/index-request.yaml"
if grep -q "1113.03" "$SANDBOX/index-request.yaml"; then
  echo "auto encrypted index leaked plaintext" >&2
  exit 1
fi
test "$(grep -c "1113.03" "$REPO/$PROTECTED_PATH")" = "1"

RHO_HOME="$SANDBOX/user1-rho-home" ./rho crypto smudge \
  --repo-root "$REPO" \
  --path "$PROTECTED_PATH" \
  < "$SANDBOX/index-request.yaml" \
  > "$SANDBOX/user1-smudged.yaml"
grep -q "1113.03" "$SANDBOX/user1-smudged.yaml"
awk '
  /^[[:space:]]+ciphertext_base64:/ && !done {
    prefix = substr($0, 1, index($0, "ciphertext_base64:") - 1)
    value = $2
    first = substr(value, 1, 1)
    replacement = first == "A" ? "B" : "A"
    print prefix "ciphertext_base64: " replacement substr(value, 2)
    done = 1
    next
  }
  { print }
' "$SANDBOX/index-request.yaml" > "$SANDBOX/index-request-tampered.yaml"
if RHO_HOME="$SANDBOX/user1-rho-home" RHO_IDENTITY="$USER1_ID" ./rho crypto smudge \
  --repo-root "$REPO" \
  --path "$PROTECTED_PATH" \
  < "$SANDBOX/index-request-tampered.yaml" \
  > "$SANDBOX/tampered-smudge-stdout.txt" \
  2> "$SANDBOX/tampered-smudge-stderr.txt"; then
  echo "smudge accepted tampered recipient envelope ciphertext for active recipient" >&2
  exit 1
fi
grep -q "recipient envelope decrypt failed for $USER1_ID" "$SANDBOX/tampered-smudge-stderr.txt"
grep -q "decrypt" "$SANDBOX/tampered-smudge-stderr.txt"
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho crypto smudge \
  --repo-root "$REPO" \
  --path "rho/messages/inbox/id/github/rho-owner/transplanted.yaml" \
  < "$SANDBOX/index-request.yaml" \
  > "$SANDBOX/transplanted-smudge-stdout.txt" \
  2> "$SANDBOX/transplanted-smudge-stderr.txt"; then
  echo "smudge accepted transplanted recipient envelope context" >&2
  exit 1
fi
grep -q "recipient envelope context mismatch" "$SANDBOX/transplanted-smudge-stderr.txt"

RHO_HOME="$SANDBOX/user2-rho-home" ./rho crypto smudge \
  --repo-root "$REPO" \
  --path "$PROTECTED_PATH" \
  < "$SANDBOX/index-request.yaml" \
  > "$SANDBOX/user2-smudged.yaml"
grep -q "1113.03" "$SANDBOX/user2-smudged.yaml"

RHO_HOME="$SANDBOX/user3-rho-home" ./rho crypto smudge \
  --repo-root "$REPO" \
  --path "$PROTECTED_PATH" \
  < "$SANDBOX/index-request.yaml" \
  > "$SANDBOX/user3-smudged.yaml"
grep -q "1113.03" "$SANDBOX/user3-smudged.yaml"

RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo sign-governance --root "$REPO" > "$SANDBOX/sign-governance.txt"
RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" > "$SANDBOX/doctor-pass.txt"
grep -q "rho repo doctor passed" "$SANDBOX/doctor-pass.txt"
grep -q "governance: passed" "$SANDBOX/doctor-pass.txt"

cat > "$SANDBOX/plaintext-bypass.yaml" <<EOF
version: 1
request:
  note: bypassed clean filter
EOF
PLAINTEXT_BLOB="$(git -C "$REPO" hash-object -w "$SANDBOX/plaintext-bypass.yaml")"
git -C "$REPO" update-index --add --cacheinfo "100644,$PLAINTEXT_BLOB,rho/messages/inbox/id/github/rho-owner/bypass.yaml"
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho repo doctor --root "$REPO" >"$SANDBOX/doctor-fail-stdout.txt" 2>"$SANDBOX/doctor-fail-stderr.txt"; then
  echo "doctor allowed bypassed plaintext protected blob" >&2
  exit 1
fi
grep -q "private-read file is not encrypted: rho/messages/inbox/id/github/rho-owner/bypass.yaml" "$SANDBOX/doctor-fail-stderr.txt"

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" \
  -path "*/.git" -prune -o \
  -maxdepth 7 -type f -print | sort
echo "rho auto encrypt policy e2e passed"
