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

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

SANDBOX="$ROOT_DIR/sandbox/rho-transparent-crypto"
REPO="$SANDBOX/repo"
RHO_HOME_DIR="$SANDBOX/rho-home"
KEY_FILE="$RHO_HOME_DIR/repo-keys/local-transparent.key"

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

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

./rho repo init \
  --root "$REPO" \
  --repo-id rho://repo/local/transparent-crypto \
  --owner rho://id/github/rho-user1 >/dev/null
RHO_HOME="$RHO_HOME_DIR" ./rho id init \
  --github rho-user1 \
  --display-name "Rho User 1" \
  --generate-ssh-key >/dev/null
RHO_HOME="$RHO_HOME_DIR" ./rho id export \
  --identity rho://id/github/rho-user1 \
  --out "$REPO/rho/participants/rho-user1.yaml" >/dev/null

RHO_HOME="$RHO_HOME_DIR" ./rho repo protect-path "secrets/**" \
  --root "$REPO" \
  --key-file "$KEY_FILE" \
  --rho-bin "$ROOT_DIR/rho" >/dev/null
grep -Fq 'pattern: "secrets/**"' "$REPO/rho/policy/permissions.yaml"
grep -q "repo_key: true" "$REPO/rho/policy/permissions.yaml"
grep -q "encryption: x25519-recipient-envelope" "$REPO/rho/policy/crypto.yaml"
grep -Fq "secrets/** filter=rho-crypt" "$REPO/.gitattributes"
./rho repo doctor --root "$REPO" --no-governance > "$SANDBOX/doctor-transparent.txt"
grep -q "rho repo doctor passed" "$SANDBOX/doctor-transparent.txt"

mkdir -p "$REPO/secrets" "$REPO/plain"
printf "the private value is 1113.03\n" > "$REPO/secrets/note.txt"
printf "public value\n" > "$REPO/plain/note.txt"

RHO_HOME="$RHO_HOME_DIR" ./rho crypto encrypt "$REPO/secrets/note.txt" \
  --key-file "$KEY_FILE" \
  --out "$SANDBOX/note.txt.rhoenc" >/dev/null
grep -q "kind: rho_transparent_file" "$SANDBOX/note.txt.rhoenc"
if grep -q "1113.03" "$SANDBOX/note.txt.rhoenc"; then
  echo "explicit rhoenc envelope leaked plaintext" >&2
  exit 1
fi
RHO_HOME="$RHO_HOME_DIR" ./rho crypto decrypt "$SANDBOX/note.txt.rhoenc" \
  --key-file "$KEY_FILE" \
  --out "$SANDBOX/note.dec.txt" >/dev/null
cmp "$REPO/secrets/note.txt" "$SANDBOX/note.dec.txt"

awk '
  /^  ciphertext_base64:/ && !done {
    value = $2
    first = substr(value, 1, 1)
    replacement = first == "A" ? "B" : "A"
    print "  ciphertext_base64: " replacement substr(value, 2)
    done = 1
    next
  }
  { print }
' "$SANDBOX/note.txt.rhoenc" > "$SANDBOX/note-tampered.txt.rhoenc"
if RHO_HOME="$RHO_HOME_DIR" ./rho crypto decrypt "$SANDBOX/note-tampered.txt.rhoenc" \
  --key-file "$KEY_FILE" \
  --out "$SANDBOX/note-tampered.dec.txt" 2>"$SANDBOX/note-tampered-error.txt"; then
  echo "transparent envelope decrypted after ciphertext tamper" >&2
  exit 1
fi
grep -q "AEAD decryption failed" "$SANDBOX/note-tampered-error.txt"

git -C "$REPO" add .gitattributes .gitignore rho plain secrets/note.txt
git -C "$REPO" show :secrets/note.txt | grep -q "kind: rho_transparent_file"
if git -C "$REPO" show :secrets/note.txt | grep -q "1113.03"; then
  echo "protected staged blob leaked plaintext" >&2
  exit 1
fi
test "$(cat "$REPO/secrets/note.txt")" = "the private value is 1113.03"
git -C "$REPO" commit -m "Add transparent encrypted secret" >/dev/null
git -C "$REPO" show HEAD:secrets/note.txt | grep -q "kind: rho_transparent_file"
if git -C "$REPO" show HEAD:secrets/note.txt | grep -q "1113.03"; then
  echo "protected committed blob leaked plaintext" >&2
  exit 1
fi

printf "this bypasses the clean filter\n" > "$SANDBOX/plaintext-bypass.txt"
PLAINTEXT_BLOB="$(git -C "$REPO" hash-object -w "$SANDBOX/plaintext-bypass.txt")"
git -C "$REPO" update-index --add --cacheinfo "100644,$PLAINTEXT_BLOB,secrets/bypass.txt"
if (cd "$REPO" && .git/hooks/pre-commit) 2>"$SANDBOX/hook-stderr.txt"; then
  echo "pre-commit hook allowed plaintext protected blob" >&2
  exit 1
fi
grep -q "protected path is staged without rho encryption: secrets/bypass.txt" "$SANDBOX/hook-stderr.txt"

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" \
  -path "*/.git" -prune -o \
  -maxdepth 5 -type f -print | sort
echo "rho transparent crypto e2e passed"
