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

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

SANDBOX="$ROOT_DIR/sandbox/rho-recipient-crypto"
REPO="$SANDBOX/repo"
USER1_ID="rho://id/github/rho-reader1"
USER2_ID="rho://id/github/rho-reader2"
USER3_ID="rho://id/github/rho-writer"
USER4_ID="rho://id/github/rho-outsider"
ENVELOPE_PATH="messages/private-result.yaml.rhoenc"

rm -rf "$SANDBOX"
mkdir -p "$REPO/rho/participants" "$REPO/messages"
cat > "$REPO/rho/repo.yaml" <<EOF
version: 1
repo:
  id: rho://repo/local/recipient-crypto
  owner: $USER3_ID
EOF
cat > "$REPO/rho/membership.yaml" <<EOF
version: 1
members:
  - identity: $USER3_ID
    role: owner
  - identity: $USER1_ID
    role: collaborator
  - identity: $USER2_ID
    role: collaborator
EOF

RHO_HOME="$SANDBOX/user1-rho-home" ./rho id init \
  --github rho-reader1 \
  --display-name "Rho Reader One" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id init \
  --github rho-reader2 \
  --display-name "Rho Reader Two" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho id init \
  --github rho-writer \
  --display-name "Rho Writer" \
  --generate-ssh-key >/dev/null
RHO_HOME="$SANDBOX/user4-rho-home" ./rho id init \
  --github rho-outsider \
  --display-name "Rho Outsider" \
  --generate-ssh-key >/dev/null

RHO_HOME="$SANDBOX/user1-rho-home" ./rho id export \
  --identity "$USER1_ID" \
  --out "$REPO/rho/participants/rho-reader1.yaml" >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho id export \
  --identity "$USER2_ID" \
  --out "$REPO/rho/participants/rho-reader2.yaml" >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho id export \
  --identity "$USER3_ID" \
  --out "$REPO/rho/participants/rho-writer.yaml" >/dev/null

grep -q "kind: age-encryption" "$REPO/rho/participants/rho-reader1.yaml"
grep -q "kind: age-encryption" "$REPO/rho/participants/rho-reader2.yaml"
grep -q "self_signature:" "$REPO/rho/participants/rho-reader1.yaml"
grep -q "self_signature:" "$REPO/rho/participants/rho-reader2.yaml"

RHO_HOME="$SANDBOX/user3-rho-home" ./rho id import \
  "$REPO/rho/participants/rho-reader1.yaml" >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho id import \
  "$REPO/rho/participants/rho-reader2.yaml" >/dev/null

cat > "$REPO/messages/private-result.yaml" <<EOF
version: 1
result:
  value: 1113.03
  note: readable by two approved recipients
EOF

RHO_HOME="$SANDBOX/user3-rho-home" ./rho crypto seal \
  "$REPO/messages/private-result.yaml" \
  --recipient "$USER1_ID" \
  --recipient "$USER2_ID" \
  --out "$REPO/$ENVELOPE_PATH" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope >/dev/null

grep -q "kind: rho_recipient_envelope" "$REPO/$ENVELOPE_PATH"
grep -q "repo_id: rho://repo/local/recipient-crypto" "$REPO/$ENVELOPE_PATH"
grep -q "path: $ENVELOPE_PATH" "$REPO/$ENVELOPE_PATH"
grep -q "purpose: rho.test_envelope" "$REPO/$ENVELOPE_PATH"
grep -q "$USER1_ID" "$REPO/$ENVELOPE_PATH"
grep -q "$USER2_ID" "$REPO/$ENVELOPE_PATH"
grep -q "$USER3_ID" "$REPO/$ENVELOPE_PATH"
if grep -q "1113.03" "$REPO/$ENVELOPE_PATH"; then
  echo "recipient envelope leaked plaintext" >&2
  exit 1
fi

RHO_HOME="$SANDBOX/user1-rho-home" ./rho crypto open \
  "$REPO/$ENVELOPE_PATH" \
  --identity "$USER1_ID" \
  --out "$SANDBOX/user1-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope >/dev/null
RHO_HOME="$SANDBOX/user2-rho-home" ./rho crypto open \
  "$REPO/$ENVELOPE_PATH" \
  --identity "$USER2_ID" \
  --out "$SANDBOX/user2-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope >/dev/null
RHO_HOME="$SANDBOX/user3-rho-home" ./rho crypto open \
  "$REPO/$ENVELOPE_PATH" \
  --identity "$USER3_ID" \
  --out "$SANDBOX/user3-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope >/dev/null

cmp "$REPO/messages/private-result.yaml" "$SANDBOX/user1-opened.yaml"
cmp "$REPO/messages/private-result.yaml" "$SANDBOX/user2-opened.yaml"
cmp "$REPO/messages/private-result.yaml" "$SANDBOX/user3-opened.yaml"

if RHO_HOME="$SANDBOX/user4-rho-home" ./rho crypto open \
  "$REPO/$ENVELOPE_PATH" \
  --identity "$USER4_ID" \
  --out "$SANDBOX/user4-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope 2>"$SANDBOX/user4-open-error.txt"; then
  echo "non-recipient opened recipient envelope" >&2
  exit 1
fi
grep -q "no recipient entry" "$SANDBOX/user4-open-error.txt"

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 }
' "$REPO/$ENVELOPE_PATH" > "$SANDBOX/private-result-tampered.yaml.rhoenc"
if RHO_HOME="$SANDBOX/user1-rho-home" ./rho crypto open \
  "$SANDBOX/private-result-tampered.yaml.rhoenc" \
  --identity "$USER1_ID" \
  --out "$SANDBOX/user1-tampered-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH" \
  --purpose rho.test_envelope 2>"$SANDBOX/user1-tampered-open-error.txt"; then
  echo "recipient envelope opened after ciphertext tamper" >&2
  exit 1
fi
grep -Eq "decrypt|invalid" "$SANDBOX/user1-tampered-open-error.txt"

if RHO_HOME="$SANDBOX/user1-rho-home" ./rho crypto open \
  "$REPO/$ENVELOPE_PATH" \
  --identity "$USER1_ID" \
  --out "$SANDBOX/wrong-path-opened.yaml" \
  --repo-root "$REPO" \
  --path "$ENVELOPE_PATH.transplanted" \
  --purpose rho.test_envelope 2>"$SANDBOX/wrong-path-error.txt"; then
  echo "opened recipient envelope with wrong context" >&2
  exit 1
fi
grep -q "recipient envelope context mismatch" "$SANDBOX/wrong-path-error.txt"

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" \
  -maxdepth 5 -type f -print | sort
echo "rho recipient crypto e2e passed"
