#!/bin/bash
# BUD-09 Blob Report Test Suite
# This test is created FIRST (TDD) and will FAIL until implementation is added to src/main.c.
#
# Expected implementation in src/main.c (BUD-09 section):
# - handle_report_request()              -> Parse and validate NIP-56 kind 1984 report events
# - validate_report_event()              -> Verify event structure, signature, and required tags
# - process_blob_report()                -> Store report, optionally take action on reported blobs
# - report_get_blob_hashes()             -> Extract SHA-256 hashes from x tags
# - report_validate_hash()               -> Validate SHA-256 format in x tags
#
# Integration points expected:
# - PUT /report endpoint accepts NIP-56 report events
# - Server validates event structure and signatures
# - Server responds with appropriate HTTP status codes
#
# Requirements:
# - curl, jq, nak (nostr army knife) must be available
# - Server should be running at http://localhost:9001 (restart-all.sh)

set -e

SERVER_URL="http://localhost:9001"
REPORT_ENDPOINT="${SERVER_URL}/report"
WORKDIR="tests/tmp_bud09"

# Test counters
TESTS_TOTAL=0
TESTS_PASSED=0
TESTS_FAILED=0

echo "=== BUD-09 Blob Report Test Suite ==="

# Prereq checks
if ! command -v curl >/dev/null 2>&1; then
  echo "ERROR: curl not found"
  exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
  echo "ERROR: jq not found (required for JSON parsing)"
  exit 1
fi
if ! command -v nak >/dev/null 2>&1; then
  echo "ERROR: nak not found (required for nostr event generation)"
  echo "Install with: go install github.com/fiatjaf/nak@latest"
  exit 1
fi

# Helper functions
log_test() {
  echo ""
  echo "=== Test $1: $2 ==="
  TESTS_TOTAL=$((TESTS_TOTAL + 1))
}

validate_response() {
  local response="$1"
  local expected_code="$2"
  local test_name="$3"
  
  local http_code=$(echo "$response" | tail -n1 | grep "HTTP_CODE:" | cut -d: -f2)
  
  if [ "$http_code" = "$expected_code" ]; then
    echo "✅ $test_name PASSED (HTTP $http_code)"
    TESTS_PASSED=$((TESTS_PASSED + 1))
  else
    echo "❌ $test_name FAILED (Expected HTTP $expected_code, got $http_code)"
    TESTS_FAILED=$((TESTS_FAILED + 1))
  fi
  
  # Show response body for debugging
  local body=$(echo "$response" | head -n -1)
  if [ -n "$body" ]; then
    echo "Response: $body"
  fi
}

generate_report_event() {
  local blob_hash="$1"
  local report_type="$2"
  local content="$3"
  
  nak event -k 1984 -c "$content" -t "x=$blob_hash;$report_type"
}

generate_multi_report_event() {
  local content="$1"
  shift
  local tags=""
  
  for arg in "$@"; do
    local hash=$(echo "$arg" | cut -d'=' -f1)
    local type=$(echo "$arg" | cut -d'=' -f2)
    tags="$tags -t x=$hash;$type"
  done
  
  nak event -k 1984 -c "$content" $tags
}

submit_report() {
  local event_json="$1"
  
  curl -s -w "\nHTTP_CODE:%{http_code}\n" \
    -X PUT \
    -H "Content-Type: application/json" \
    -d "$event_json" \
    "$REPORT_ENDPOINT"
}

# Create temporary working directory
mkdir -p "$WORKDIR"

# Test data - valid SHA-256 hashes
HASH1="deadbeefcafebabe0123456789abcdef0123456789abcdef0123456789abcdef"
HASH2="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
HASH3="abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
INVALID_HASH="invalid_hash_format"

echo ""
echo "Test Configuration:"
echo "  Server: $SERVER_URL"
echo "  Report endpoint: $REPORT_ENDPOINT"
echo "  Working directory: $WORKDIR"
echo "  Test hashes: $HASH1, $HASH2, $HASH3"

# Test 1: Valid Single Blob Report (nudity)
log_test 1 "Valid Single Blob Report (nudity)"
EVENT1=$(generate_report_event "$HASH1" "nudity" "This image contains inappropriate content")
echo "Event: $EVENT1"
RESPONSE1=$(submit_report "$EVENT1")
validate_response "$RESPONSE1" "200" "Test 1"

# Test 2: Multiple Blob Report (malware)
log_test 2 "Multiple Blob Report (malware)"
EVENT2=$(generate_multi_report_event "Multiple files contain malware" "${HASH1}=malware" "${HASH2}=malware")
echo "Event: $EVENT2"
RESPONSE2=$(submit_report "$EVENT2")
validate_response "$RESPONSE2" "200" "Test 2"

# Test 3: Report Types Coverage - nudity
log_test 3a "Report Type: nudity"
EVENT3A=$(generate_report_event "$HASH1" "nudity" "Nudity content reported")
RESPONSE3A=$(submit_report "$EVENT3A")
validate_response "$RESPONSE3A" "200" "Test 3a (nudity)"

# Test 3: Report Types Coverage - malware
log_test 3b "Report Type: malware"
EVENT3B=$(generate_report_event "$HASH2" "malware" "Malware content reported")
RESPONSE3B=$(submit_report "$EVENT3B")
validate_response "$RESPONSE3B" "200" "Test 3b (malware)"

# Test 3: Report Types Coverage - profanity
log_test 3c "Report Type: profanity"
EVENT3C=$(generate_report_event "$HASH3" "profanity" "Profanity content reported")
RESPONSE3C=$(submit_report "$EVENT3C")
validate_response "$RESPONSE3C" "200" "Test 3c (profanity)"

# Test 3: Report Types Coverage - illegal
log_test 3d "Report Type: illegal"
EVENT3D=$(generate_report_event "$HASH1" "illegal" "Illegal content reported")
RESPONSE3D=$(submit_report "$EVENT3D")
validate_response "$RESPONSE3D" "200" "Test 3d (illegal)"

# Test 3: Report Types Coverage - spam
log_test 3e "Report Type: spam"
EVENT3E=$(generate_report_event "$HASH2" "spam" "Spam content reported")
RESPONSE3E=$(submit_report "$EVENT3E")
validate_response "$RESPONSE3E" "200" "Test 3e (spam)"

# Test 3: Report Types Coverage - impersonation
log_test 3f "Report Type: impersonation"
EVENT3F=$(generate_report_event "$HASH3" "impersonation" "Impersonation content reported")
RESPONSE3F=$(submit_report "$EVENT3F")
validate_response "$RESPONSE3F" "200" "Test 3f (impersonation)"

# Test 3: Report Types Coverage - other
log_test 3g "Report Type: other"
EVENT3G=$(generate_report_event "$HASH1" "other" "Other type of inappropriate content")
RESPONSE3G=$(submit_report "$EVENT3G")
validate_response "$RESPONSE3G" "200" "Test 3g (other)"

# Test 4: Report with Optional Tags (comprehensive NIP-56 structure)
log_test 4 "Report with Optional Tags"
EVENT4=$(nak event -k 1984 -c "Comprehensive report with all tags" \
  -t "x=${HASH1};spam" \
  -t "e=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" \
  -t "p=abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" \
  -t "server=https://example.com/blob.jpg")
echo "Event: $EVENT4"
RESPONSE4=$(submit_report "$EVENT4")
validate_response "$RESPONSE4" "200" "Test 4"

# Test 5: Missing x Tags Error
log_test 5 "Missing x Tags Error"
EVENT5=$(nak event -k 1984 -c "Report without x tags" -t "p=somekey")
echo "Event: $EVENT5"
RESPONSE5=$(submit_report "$EVENT5")
validate_response "$RESPONSE5" "400" "Test 5"

# Test 6: Invalid SHA-256 Format
log_test 6 "Invalid SHA-256 Format"
EVENT6=$(generate_report_event "$INVALID_HASH" "nudity" "Invalid hash format test")
echo "Event: $EVENT6"
RESPONSE6=$(submit_report "$EVENT6")
validate_response "$RESPONSE6" "400" "Test 6"

# Test 7: Wrong Event Kind
log_test 7 "Wrong Event Kind"
EVENT7=$(nak event -k 1 -c "Wrong kind test" -t "x=${HASH1};nudity")
echo "Event: $EVENT7"
RESPONSE7=$(submit_report "$EVENT7")
validate_response "$RESPONSE7" "400" "Test 7"

# Test 8: Invalid JSON Structure
log_test 8 "Invalid JSON Structure"
INVALID_JSON='{"invalid":"json","missing":}'
echo "Invalid JSON: $INVALID_JSON"
RESPONSE8=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X PUT \
  -H "Content-Type: application/json" \
  -d "$INVALID_JSON" \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE8" "400" "Test 8"

# Test 9: Unsupported HTTP Method - GET
log_test 9a "Unsupported Method: GET"
RESPONSE9A=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X GET \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE9A" "405" "Test 9a (GET)"

# Test 9: Unsupported HTTP Method - POST
log_test 9b "Unsupported Method: POST"
RESPONSE9B=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"test":"post"}' \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE9B" "405" "Test 9b (POST)"

# Test 9: Unsupported HTTP Method - DELETE
log_test 9c "Unsupported Method: DELETE"
RESPONSE9C=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X DELETE \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE9C" "405" "Test 9c (DELETE)"

# Test 10: Empty Request Body
log_test 10 "Empty Request Body"
RESPONSE10=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X PUT \
  -H "Content-Type: application/json" \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE10" "400" "Test 10"

# Test 11: Unknown Report Type (should be accepted per spec)
log_test 11 "Unknown Report Type"
EVENT11=$(generate_report_event "$HASH1" "unknown_type" "Unknown report type test")
echo "Event: $EVENT11"
RESPONSE11=$(submit_report "$EVENT11")
validate_response "$RESPONSE11" "200" "Test 11"

# Test 12: Invalid Content-Type
log_test 12 "Invalid Content-Type"
EVENT12=$(generate_report_event "$HASH1" "nudity" "Content type test")
RESPONSE12=$(curl -s -w "\nHTTP_CODE:%{http_code}\n" \
  -X PUT \
  -H "Content-Type: text/plain" \
  -d "$EVENT12" \
  "$REPORT_ENDPOINT")
validate_response "$RESPONSE12" "415" "Test 12"

# Test 13: Valid report with empty content field
log_test 13 "Empty Content Field"
EVENT13=$(generate_report_event "$HASH1" "spam" "")
echo "Event: $EVENT13"
RESPONSE13=$(submit_report "$EVENT13")
validate_response "$RESPONSE13" "200" "Test 13"

# Test 14: Very long content field
log_test 14 "Long Content Field"
LONG_CONTENT=$(printf 'A%.0s' {1..1000})
EVENT14=$(generate_report_event "$HASH1" "other" "$LONG_CONTENT")
RESPONSE14=$(submit_report "$EVENT14")
validate_response "$RESPONSE14" "200" "Test 14"

# Cleanup
rm -rf "$WORKDIR"

# Test Summary
echo ""
echo "=== BUD-09 Test Summary ==="
echo "Total tests: $TESTS_TOTAL"
echo "Passed: $TESTS_PASSED"
echo "Failed: $TESTS_FAILED"
echo ""

if [ "$TESTS_FAILED" -eq 0 ]; then
  echo "🎉 All tests passed! BUD-09 implementation is working correctly."
  exit 0
else
  echo "❌ $TESTS_FAILED test(s) failed. BUD-09 implementation needs fixes."
  exit 1
fi

echo "=== End of BUD-09 Blob Report Test Suite ==="