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

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

SANDBOX="$ROOT_DIR/sandbox/rho-id-github"
USER1_HOME="$SANDBOX/user1-rho-home"
USER2_HOME="$SANDBOX/user2-rho-home"
REUSE_HOME="$SANDBOX/reuse-rho-home"
EXPORT_DIR="$SANDBOX/repo/.rho/participants"
REQUEST_PATH="$SANDBOX/repo/.rho/requests/request-from-user2.yaml"
SIGNATURE_PATH="$SANDBOX/repo/.rho/requests/request-from-user2.rhosig.yaml"
CONTEXT_SIGNATURE_PATH="$SANDBOX/repo/.rho/requests/request-from-user2.context.rhosig.yaml"
USER1_ID="rho://id/github/rho-user1"
USER2_ID="rho://id/github/rho-user2"
REPO_ID="rho://repo/github/rho-owner/rho-context"

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

USER1_OUTPUT="$(RHO_HOME="$USER1_HOME" ./rho id init \
  --github rho-user1 \
  --display-name "Rho User One" \
  --generate-ssh-key)"
USER2_OUTPUT="$(RHO_HOME="$USER2_HOME" ./rho id init \
  --github rho-user2 \
  --display-name "Rho User Two" \
  --generate-ssh-key)"

echo "$USER1_OUTPUT" | grep -q "$USER1_ID"
echo "$USER1_OUTPUT" | grep -q "https://github.com/rho-user1#rho.claim/id/github/rho-user1/key/ssh-ed25519/"
echo "$USER2_OUTPUT" | grep -q "$USER2_ID"
echo "$USER2_OUTPUT" | grep -q "https://github.com/rho-user2#rho.claim/id/github/rho-user2/key/ssh-ed25519/"
echo "$USER1_OUTPUT" | grep -q "signing key source: generated"
echo "$USER1_OUTPUT" | grep -q "encryption key source: generated"

REUSE_FIRST_OUTPUT="$(RHO_HOME="$REUSE_HOME" ./rho id init github/rho-reuse --display-name "Rho Reuse" --yes)"
echo "$REUSE_FIRST_OUTPUT" | grep -q "signing key source: generated default"
echo "$REUSE_FIRST_OUTPUT" | grep -q "encryption key source: generated default"
rm "$REUSE_HOME/identities/github/rho-reuse.yaml"
REUSE_SECOND_OUTPUT="$(RHO_HOME="$REUSE_HOME" ./rho id init github/rho-reuse --display-name "Rho Reuse" --yes)"
echo "$REUSE_SECOND_OUTPUT" | grep -q "signing key source: reused default"
echo "$REUSE_SECOND_OUTPUT" | grep -q "encryption key source: reused default"
REUSE_OLD_PUBLIC="$REUSE_HOME/keys/github/rho-reuse/signing_ed25519.pub"
test -f "$REUSE_OLD_PUBLIC"
REUSE_ROTATE_OUTPUT="$(RHO_HOME="$REUSE_HOME" ./rho id rotate-key github/rho-reuse --yes)"
echo "$REUSE_ROTATE_OUTPUT" | grep -q "rotated signing key"
echo "$REUSE_ROTATE_OUTPUT" | grep -q "key_id: rho://key/github/rho-reuse/ssh-ed25519-2"
echo "$REUSE_ROTATE_OUTPUT" | grep -q "github proof: unverified"
REUSE_NEW_PUBLIC="$(printf "%s\n" "$REUSE_ROTATE_OUTPUT" | sed -n 's/^public key: //p')"
test -n "$REUSE_NEW_PUBLIC"
test "$REUSE_NEW_PUBLIC" != "$REUSE_OLD_PUBLIC"
test -f "$REUSE_OLD_PUBLIC"
test -f "$REUSE_NEW_PUBLIC"
grep -q "rho://key/github/rho-reuse/ssh-ed25519-1" "$REUSE_HOME/identities/github/rho-reuse.yaml"
grep -q "rho://key/github/rho-reuse/ssh-ed25519-2" "$REUSE_HOME/identities/github/rho-reuse.yaml"
RHO_HOME="$REUSE_HOME" ./rho id status github/rho-reuse > "$SANDBOX/reuse-status-after-rotate.txt"
grep -q "github proof: unverified" "$SANDBOX/reuse-status-after-rotate.txt"
printf "rotation check\n" > "$SANDBOX/reuse-message.txt"
RHO_HOME="$REUSE_HOME" ./rho crypto sign \
  "$SANDBOX/reuse-message.txt" \
  --identity rho://id/github/rho-reuse \
  --out "$SANDBOX/reuse-message.rhosig.yaml" >/dev/null
grep -q "key_id: rho://key/github/rho-reuse/ssh-ed25519-2" "$SANDBOX/reuse-message.rhosig.yaml"

test -f "$USER1_HOME/keys/github/rho-user1/signing_ed25519"
test -f "$USER1_HOME/keys/github/rho-user1/signing_ed25519.pub"
test -f "$USER2_HOME/keys/github/rho-user2/signing_ed25519"
test -f "$USER2_HOME/keys/github/rho-user2/signing_ed25519.pub"

RHO_HOME="$USER1_HOME" ./rho id status "$USER1_ID" > "$SANDBOX/user1-status-before-verify.txt"
grep -q "identity: $USER1_ID" "$SANDBOX/user1-status-before-verify.txt"
grep -q "private key: present" "$SANDBOX/user1-status-before-verify.txt"
grep -q "github proof: unverified" "$SANDBOX/user1-status-before-verify.txt"
grep -q "proof_url: https://github.com/rho-user1#rho.claim/id/github/rho-user1/key/ssh-ed25519/" "$SANDBOX/user1-status-before-verify.txt"

RHO_HOME="$USER1_HOME" ./rho id export \
  --identity "$USER1_ID" \
  --out "$EXPORT_DIR/rho-user1.yaml"
RHO_HOME="$USER2_HOME" ./rho id export \
  --identity "$USER2_ID" \
  --out "$EXPORT_DIR/rho-user2.yaml"

grep -q "$USER1_ID" "$EXPORT_DIR/rho-user1.yaml"
grep -q "github-profile-fragment-claim" "$EXPORT_DIR/rho-user1.yaml"
grep -q "provider_url: https://github.com/rho-user1" "$EXPORT_DIR/rho-user1.yaml"
grep -q "claim: rho.claim/id/github/rho-user1/key/ssh-ed25519/" "$EXPORT_DIR/rho-user1.yaml"
grep -q "proof_url: https://github.com/rho-user1#rho.claim/id/github/rho-user1/key/ssh-ed25519/" "$EXPORT_DIR/rho-user1.yaml"
grep -q "ssh-ed25519" "$EXPORT_DIR/rho-user1.yaml"

RHO_HOME="$USER1_HOME" ./rho id import "$EXPORT_DIR/rho-user2.yaml"
RHO_HOME="$USER2_HOME" ./rho id import "$EXPORT_DIR/rho-user1.yaml"

USER1_CLAIM="$(sed -n 's/^    claim: //p' "$EXPORT_DIR/rho-user1.yaml")"
USER2_CLAIM="$(sed -n 's/^    claim: //p' "$EXPORT_DIR/rho-user2.yaml")"
cat > "$SANDBOX/github-rho-user1.html" <<EOF
<html><body><a href="https://example.com">$USER1_CLAIM</a></body></html>
EOF
cat > "$SANDBOX/github-rho-user2.html" <<EOF
<html><body><a href="https://example.com">$USER2_CLAIM</a></body></html>
EOF

RHO_HOME="$USER1_HOME" ./rho id verify-github \
  --identity "$USER2_ID" \
  --provider-file "$SANDBOX/github-rho-user2.html"
RHO_HOME="$USER2_HOME" ./rho id verify-github \
  --identity "$USER1_ID" \
  --provider-file "$SANDBOX/github-rho-user1.html"

grep -q "verified_at:" "$USER1_HOME/peers/github/rho-user2.yaml"
grep -q "verified_at:" "$USER2_HOME/peers/github/rho-user1.yaml"

RHO_HOME="$USER1_HOME" ./rho id status "$USER2_ID" > "$SANDBOX/user2-status-after-verify.txt"
grep -q "identity: $USER2_ID" "$SANDBOX/user2-status-after-verify.txt"
grep -q "private key: not-present" "$SANDBOX/user2-status-after-verify.txt"
grep -q "github proof: verified" "$SANDBOX/user2-status-after-verify.txt"
grep -q "verified_at:" "$SANDBOX/user2-status-after-verify.txt"

mkdir -p "$(dirname "$REQUEST_PATH")"
cat > "$REQUEST_PATH" <<EOF
version: 1
request:
  id: req-rho-id-github-signature
  from: $USER2_ID
  to: $USER1_ID
  body: please run the approved aggregate
EOF

RHO_HOME="$USER2_HOME" ./rho crypto sign "$REQUEST_PATH" \
  --identity "$USER2_ID" \
  --out "$SIGNATURE_PATH"
grep -q "$USER2_ID" "$SIGNATURE_PATH"
grep -q "namespace: rho" "$SIGNATURE_PATH"
grep -q "BEGIN SSH SIGNATURE" "$SIGNATURE_PATH"

RHO_HOME="$USER1_HOME" ./rho crypto verify "$REQUEST_PATH" \
  --signature "$SIGNATURE_PATH" \
  --identity "$USER2_ID"

RHO_HOME="$USER2_HOME" ./rho crypto sign "$REQUEST_PATH" \
  --identity "$USER2_ID" \
  --repo-id "$REPO_ID" \
  --request-id req-rho-id-github-signature \
  --recipient "$USER1_ID" \
  --purpose request \
  --out "$CONTEXT_SIGNATURE_PATH"
grep -q "context:" "$CONTEXT_SIGNATURE_PATH"
grep -q "$REPO_ID" "$CONTEXT_SIGNATURE_PATH"
grep -q "recipient_id: $USER1_ID" "$CONTEXT_SIGNATURE_PATH"

RHO_HOME="$USER1_HOME" ./rho crypto verify "$REQUEST_PATH" \
  --signature "$CONTEXT_SIGNATURE_PATH" \
  --identity "$USER2_ID" \
  --repo-id "$REPO_ID" \
  --request-id req-rho-id-github-signature \
  --recipient "$USER1_ID" \
  --purpose request

if RHO_HOME="$USER1_HOME" ./rho crypto verify "$REQUEST_PATH" \
  --signature "$CONTEXT_SIGNATURE_PATH" \
  --identity "$USER2_ID" \
  --repo-id "$REPO_ID" \
  --request-id req-rho-id-github-wrong \
  --recipient "$USER1_ID" \
  --purpose request; then
  echo "wrong signature context unexpectedly verified" >&2
  exit 1
fi

printf "\n# tamper\n" >> "$REQUEST_PATH"
if RHO_HOME="$USER1_HOME" ./rho crypto verify "$REQUEST_PATH" \
  --signature "$SIGNATURE_PATH" \
  --identity "$USER2_ID"; then
  echo "tampered signature unexpectedly verified" >&2
  exit 1
fi

RHO_HOME="$USER1_HOME" ./rho id trust "$USER2_ID"
RHO_HOME="$USER2_HOME" ./rho id trust "$USER1_ID"

test -f "$USER1_HOME/peers/github/rho-user2.yaml"
test -f "$USER2_HOME/peers/github/rho-user1.yaml"
grep -q "trusted" "$USER1_HOME/trust/github/rho-user2.yaml"
grep -q "trusted" "$USER2_HOME/trust/github/rho-user1.yaml"

echo "inspect sandbox: $SANDBOX"
find "$SANDBOX" -maxdepth 5 -type f | sort
echo "rho id github e2e passed"
