#!/bin/bash
# otp_roundtrip_test.sh — end-to-end test of otp_encrypt / otp_decrypt verbs.
#
# Sends framed JSON-RPC requests to nsigner --listen stdio and checks the
# round-trip: plaintext -> otp_encrypt -> otp_decrypt -> recovered plaintext.
#
# Usage: ./tools/otp_roundtrip_test.sh
set -euo pipefail

NSIGNER="./build/nsigner"
PAD_DIR="/media/user/Music/pads"
PAD_SPEC="333e9902db839d9d"
MNEMONIC_FILE=".test_mnemonic"

if [ ! -x "$NSIGNER" ]; then
    echo "ERROR: $NSIGNER not found. Run 'make dev' first."
    exit 1
fi

# Helper: send a framed JSON-RPC request to nsigner stdio and print the response.
# Framing: 4-byte big-endian length prefix + JSON payload.
send_request() {
    local json="$1"
    local len=${#json}
    # 4-byte big-endian length
    printf '\\x%02x\\x%02x\\x%02x\\x%02x' \
        $(( (len >> 24) & 0xff )) $(( (len >> 16) & 0xff )) \
        $(( (len >> 8) & 0xff ))  $(( len & 0xff ))
    printf '%s' "$json"
}

# Build the plaintext base64. "Hello, OTP world!" -> base64
PLAINTEXT_B64=$(printf 'Hello, OTP world!' | base64)
echo "Plaintext base64: $PLAINTEXT_B64"

# Build the encrypt request
ENCRYPT_REQ=$(cat <<EOF
{"id":"1","method":"otp_encrypt","params":["$PLAINTEXT_B64",{"encoding":"ascii"}]}
EOF
)

echo "=== Sending otp_encrypt ==="
RESPONSE=$( (printf '\\x00\\x00\\x00\\x%02x' ${#ENCRYPT_REQ}; printf '%s' "$ENCRYPT_REQ") | \
    (exec 3<"$MNEMONIC_FILE"; "$NSIGNER" --listen stdio --mnemonic-fd 3 \
        --otp-pad-dir "$PAD_DIR" --otp-pad "$PAD_SPEC" --otp-allow-blkback --allow-all) 2>/dev/null \
    | tail -1 )

echo "Encrypt response: $RESPONSE"

# Extract the ciphertext field (rough parse — look for "ciphertext":"...")
CIPHERTEXT=$(echo "$RESPONSE" | sed -n 's/.*"ciphertext":"\([^"]*\)".*/\1/p')
if [ -z "$CIPHERTEXT" ]; then
    echo "ERROR: no ciphertext in response"
    exit 1
fi
echo "Ciphertext (first 80 chars): ${CIPHERTEXT:0:80}..."

# Build the decrypt request — the ciphertext is the ASCII armor (with newlines
# escaped as \n in JSON). We need to properly JSON-escape it.
# Use python to do the JSON encoding safely.
DECRYPT_REQ=$(python3 -c "
import json, sys
ct = sys.argv[1]
print(json.dumps({'id':'2','method':'otp_decrypt','params':[ct,{'encoding':'ascii'}]}))
" "$CIPHERTEXT")

echo "=== Sending otp_decrypt ==="
RESPONSE2=$( (printf '\\x00\\x00\\x00\\x%02x' ${#DECRYPT_REQ}; printf '%s' "$DECRYPT_REQ") | \
    (exec 3<"$MNEMONIC_FILE"; "$NSIGNER" --listen stdio --mnemonic-fd 3 \
        --otp-pad-dir "$PAD_DIR" --otp-pad "$PAD_SPEC" --otp-allow-blkback --allow-all) 2>/dev/null \
    | tail -1 )

echo "Decrypt response: $RESPONSE2"

# Extract and decode the recovered plaintext
RECOVERED_B64=$(echo "$RESPONSE2" | sed -n 's/.*"plaintext":"\([^"]*\)".*/\1/p')
if [ -z "$RECOVERED_B64" ]; then
    echo "ERROR: no plaintext in decrypt response"
    exit 1
fi
RECOVERED=$(echo "$RECOVERED_B64" | base64 -d 2>/dev/null)
echo "Recovered plaintext: $RECOVERED"

if [ "$RECOVERED" = "Hello, OTP world!" ]; then
    echo ""
    echo "=== ROUND-TRIP SUCCESS ==="
    exit 0
else
    echo ""
    echo "=== ROUND-TRIP FAILED ==="
    echo "Expected: Hello, OTP world!"
    echo "Got:      $RECOVERED"
    exit 1
fi
