#!/bin/bash
set -e

echo "╔══════════════════════════════════════════════════════════════╗"
echo "║         SECURITY HARDENING ACCEPTANCE TESTS                  ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""

PASSED=0
FAILED=0

PAYLOAD='{"org_id":"00000000-0000-0000-0000-000000000000","user_id":"00000000-0000-0000-0000-000000000001","queries":["test"],"top_k":1}'

# Test 1: DB ports not accessible from host
echo "=== Test 1: DB Network Isolation ==="
for port in 5432 6333 7474 6379; do
    if timeout 2 nc -zv localhost $port 2>&1 | grep -q "succeeded"; then
        echo "❌ FAIL: Port $port is accessible from host"
        FAILED=$((FAILED + 1))
    else
        echo "✅ PASS: Port $port is not accessible"
        PASSED=$((PASSED + 1))
    fi
done

# Test 2: Memory API requires JWT
echo ""
echo "=== Test 2: Memory API JWT Protection ==="
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/retrieve -X POST -H "Content-Type: application/json" -d "$PAYLOAD" || true)
if [ "$RESPONSE" = "401" ]; then
    echo "✅ PASS: Memory API requires authentication"
    PASSED=$((PASSED + 1))
elif [ "$RESPONSE" = "000" ]; then
    echo "ℹ️ Host access blocked (expected). Testing inside container..."
    INTERNAL=$(cat << 'PY' | docker exec -i dagi-memory-service-node1 python3 -
import urllib.request, urllib.error
payload = b'{"org_id":"00000000-0000-0000-0000-000000000000","user_id":"00000000-0000-0000-0000-000000000001","queries":["test"],"top_k":1}'
req = urllib.request.Request("http://localhost:8000/retrieve", data=payload, headers={"Content-Type":"application/json"}, method="POST")
try:
    with urllib.request.urlopen(req, timeout=3) as resp:
        print(resp.status)
except urllib.error.HTTPError as e:
    print(e.code)
except Exception:
    print("ERR")
PY
)
    if [ "$INTERNAL" = "401" ]; then
        echo "✅ PASS: Memory API requires authentication (internal)"
        PASSED=$((PASSED + 1))
    else
        echo "❌ FAIL: Memory API auth check failed (internal got $INTERNAL)"
        FAILED=$((FAILED + 1))
    fi
else
    echo "❌ FAIL: Memory API does not require auth (got $RESPONSE)"
    FAILED=$((FAILED + 1))
fi

# Test 3: Control Plane requires JWT
echo ""
echo "=== Test 3: Control Plane JWT Protection ==="
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9200/prompts/helion || true)
if [ "$RESPONSE" = "401" ]; then
    echo "✅ PASS: Control Plane requires authentication"
    PASSED=$((PASSED + 1))
elif [ "$RESPONSE" = "000" ]; then
    echo "ℹ️ Host access blocked (expected). Testing inside container..."
    INTERNAL=$(cat << 'PY' | docker exec -i control-plane python3 -
import urllib.request, urllib.error
req = urllib.request.Request("http://localhost:9200/prompts/helion")
try:
    with urllib.request.urlopen(req, timeout=3) as resp:
        print(resp.status)
except urllib.error.HTTPError as e:
    print(e.code)
except Exception:
    print("ERR")
PY
)
    if [ "$INTERNAL" = "401" ]; then
        echo "✅ PASS: Control Plane requires authentication (internal)"
        PASSED=$((PASSED + 1))
    else
        echo "❌ FAIL: Control Plane auth check failed (internal got $INTERNAL)"
        FAILED=$((FAILED + 1))
    fi
else
    echo "❌ FAIL: Control Plane does not require auth (got $RESPONSE)"
    FAILED=$((FAILED + 1))
fi

# Test 4: Gateway public access

echo ""
echo "=== Test 4: Gateway Public Access ==="
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9300/health || true)
if [ "$RESPONSE" = "200" ]; then
    echo "✅ PASS: Gateway is publicly accessible"
    PASSED=$((PASSED + 1))
else
    echo "⚠️ WARN: Gateway health check returned $RESPONSE"
fi

# Summary

echo ""
echo "═══════════════════════════════════════════════════════════════"
echo "                    TEST SUMMARY"
echo "═══════════════════════════════════════════════════════════════"
echo "Passed: $PASSED"
echo "Failed: $FAILED"
echo ""

if [ $FAILED -eq 0 ]; then
    echo "✅ All critical tests passed!"
    exit 0
else
    echo "⚠️ Some tests failed - review required"
    exit 1
fi
