#!/bin/bash

# Source the environment with DIDs
if [ ! -f .generated/test-env.sh ]; then
    echo "Error: No test environment found. Run run-deeplink-tests.sh first"
    exit 1
fi
source .generated/test-env.sh

# Verify we have the required DIDs
if [ -z "$CONTACT1_DID" ] || [ -z "$CONTACT1_KEY" ]; then
    echo "Error: Contact1 DID info not found in environment"
    exit 1
fi

# Use CONTACT1 as the issuer since we know it's registered
REGISTERED_DID="$CONTACT1_DID"
REGISTERED_KEY="$CONTACT1_KEY"

# Default API URL (can be overridden by environment)
API_URL=${ENDORSER_API_URL:-"https://test-api.endorser.ch/api/v2/claim"}

# Function to sign a message using ES256K
sign_message() {
    local message="$1"
    local private_key="$2"
    local tmpdir

    # Create temporary directory
    tmpdir=$(mktemp -d)
    trap 'rm -rf "$tmpdir"' EXIT

    # Debug output
    echo "Signing message: $message" >&2
    echo "Using private key: $private_key" >&2

    # Hash the message with SHA-256
    echo -n "$message" | openssl dgst -sha256 -binary > "$tmpdir/message.hash"

    # Sign the hash directly using the private key
    # This avoids OpenSSL's PEM format issues with secp256k1
    python3 -c "
import sys
from eth_keys import keys
import hashlib

# Read message hash
with open('$tmpdir/message.hash', 'rb') as f:
    message_hash = f.read()

# Create private key object
private_key_bytes = bytes.fromhex('$private_key')
private_key = keys.PrivateKey(private_key_bytes)

# Sign the message hash
signature = private_key.sign_msg_hash(message_hash)

# Output R and S values as hex
print(f'{hex(signature.r)[2:]:0>64}')
print(f'{hex(signature.s)[2:]:0>64}')
" > "$tmpdir/signature.txt"

    # Read R and S values
    { read -r r_val; read -r s_val; } < "$tmpdir/signature.txt"

    # Debug R and S values
    echo "R value: $r_val" >&2
    echo "S value: $s_val" >&2

    # Concatenate R+S and convert to base64url
    echo -n "${r_val}${s_val}" | xxd -r -p | base64 -w 0 | tr '/+' '_-' | tr -d '='
}

# Create a test claim payload
create_claim_payload() {
    local issuer_did="$1"
    
    # Create a test claim matching the app's structure
    cat << EOF
{
    "@context": "https://schema.org",
    "@type": "TestClaim",
    "identifier": "test-claim-$(date +%s)",
    "name": "Test Claim",
    "description": "Generated test claim",
    "agent": {
        "did": "$issuer_did"
    }
}
EOF
}

# Create and sign JWT
create_jwt() {
    local claim="$1"
    local issuer_did="$2"
    local private_key="$3"
    
    # Create header and payload matching the app's structure
    local header='{"typ":"JWT","alg":"ES256K"}'
    local payload="{\"iat\":$(date +%s),\"exp\":$(($(date +%s) + 300)),\"iss\":\"$issuer_did\",\"vc\":{\"@context\":[\"https://www.w3.org/2018/credentials/v1\"],\"type\":[\"VerifiableCredential\"],\"credentialSubject\":$claim}}"

    # Base64url encode header and payload
    local header_b64=$(echo -n "$header" | base64 -w 0 | tr '/+' '_-' | tr -d '=')
    local payload_b64=$(echo -n "$payload" | base64 -w 0 | tr '/+' '_-' | tr -d '=')
    
    # Create message to sign
    local message="$header_b64.$payload_b64"
    
    # Sign message using eth_keys (same as did-jwt library)
    local signature=$(python3 -c "
from eth_keys import keys
import hashlib

# Create private key object
private_key_bytes = bytes.fromhex('$private_key')
private_key = keys.PrivateKey(private_key_bytes)

# Hash the message
message_hash = hashlib.sha256('$message'.encode()).digest()

# Sign using ES256K
signature = private_key.sign_msg_hash(message_hash)

# Format as R+S concatenated and base64url encoded
import base64
signature_bytes = signature.r.to_bytes(32, 'big') + signature.s.to_bytes(32, 'big')
print(base64.urlsafe_b64encode(signature_bytes).decode().rstrip('='))
")

    # Return complete JWT
    echo "$message.$signature"
}

# Function to register claim with API
register_claim() {
    local jwt="$1"
    
    echo "Registering claim with API..."
    response=$(curl -s -X POST "$API_URL" \
         -H "Content-Type: application/json" \
         -d "{\"jwtEncoded\":\"$jwt\"}")
    
    # Check response
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        echo "Registration successful!"
        echo "Response:"
        echo "$response" | jq '.'
        return 0
    else
        echo "Registration failed!"
        echo "Error: $(echo "$response" | jq -r '.error.message // empty')"
        echo "Full response:"
        echo "$response" | jq '.' || echo "$response"
        return 1
    fi
}

# Main execution
echo "Generating test claim..."

# Create claim payload
claim=$(create_claim_payload "$REGISTERED_DID")
echo "Claim payload:"
echo "$claim" | jq '.'

# Create and sign JWT
echo "Generating signed JWT..."
jwt=$(create_jwt "$claim" "$REGISTERED_DID" "$REGISTERED_KEY")

# Output just the JWT for piping
echo "$jwt"

# Register the claim
register_claim "$jwt"