#!/bin/bash
# Performance Testing Script
# Uses k6, Apache Bench, or curl for load testing

set -e

# Configuration
API_URL="${API_URL:-https://api.sankofa.nexus}"
PORTAL_URL="${PORTAL_URL:-https://portal.sankofa.nexus}"
TEST_DURATION="${TEST_DURATION:-60s}"
VUS="${VUS:-10}" # Virtual Users

# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Check for k6
if command -v k6 &> /dev/null; then
    log_info "Using k6 for load testing"
    USE_K6=true
elif command -v ab &> /dev/null; then
    log_info "Using Apache Bench for load testing"
    USE_K6=false
    USE_AB=true
else
    log_error "Neither k6 nor Apache Bench found. Install k6: https://k6.io/docs/getting-started/installation/"
    exit 1
fi

# Create k6 test script
create_k6_script() {
    cat > /tmp/k6_test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';

const errorRate = new Rate('errors');

export const options = {
    stages: [
        { duration: '30s', target: 10 },  // Ramp up
        { duration: '1m', target: 10 },   // Stay at 10 VUs
        { duration: '30s', target: 20 },  // Ramp up to 20
        { duration: '1m', target: 20 },   // Stay at 20 VUs
        { duration: '30s', target: 0 },  // Ramp down
    ],
    thresholds: {
        'http_req_duration': ['p(95)<200'], // 95% of requests should be below 200ms
        'http_req_failed': ['rate<0.01'],   // Error rate should be less than 1%
        'errors': ['rate<0.01'],
    },
};

const API_URL = __ENV.API_URL || 'https://api.sankofa.nexus';

export default function () {
    // Test health endpoint
    const healthRes = http.get(`${API_URL}/health`);
    const healthCheck = check(healthRes, {
        'health status is 200': (r) => r.status === 200,
        'health response time < 100ms': (r) => r.timings.duration < 100,
    });
    errorRate.add(!healthCheck);

    // Test GraphQL endpoint
    const graphqlPayload = JSON.stringify({
        query: '{ __typename }',
    });
    const graphqlRes = http.post(`${API_URL}/graphql`, graphqlPayload, {
        headers: { 'Content-Type': 'application/json' },
    });
    const graphqlCheck = check(graphqlRes, {
        'graphql status is 200': (r) => r.status === 200,
        'graphql response time < 200ms': (r) => r.timings.duration < 200,
        'graphql has data': (r) => JSON.parse(r.body).data !== undefined,
    });
    errorRate.add(!graphqlCheck);

    sleep(1);
}
EOF
}

# Run k6 test
run_k6_test() {
    log_info "Starting k6 load test..."
    log_info "Duration: ${TEST_DURATION}"
    log_info "Virtual Users: ${VUS}"
    log_info "API URL: ${API_URL}"
    echo ""
    
    k6 run --env API_URL="${API_URL}" \
        --duration "${TEST_DURATION}" \
        --vus "${VUS}" \
        /tmp/k6_test.js
}

# Run Apache Bench test
run_ab_test() {
    log_info "Starting Apache Bench load test..."
    log_info "Requests: 1000"
    log_info "Concurrency: ${VUS}"
    log_info "API URL: ${API_URL}"
    echo ""
    
    # Test health endpoint
    log_info "Testing /health endpoint..."
    ab -n 1000 -c "${VUS}" -k "${API_URL}/health"
    
    echo ""
    log_info "Testing GraphQL endpoint..."
    echo '{"query": "{ __typename }"}' > /tmp/graphql_payload.json
    ab -n 1000 -c "${VUS}" -k -p /tmp/graphql_payload.json \
        -T 'application/json' \
        "${API_URL}/graphql"
}

# Simple curl-based test
run_curl_test() {
    log_info "Running simple curl-based performance test..."
    log_info "This is a basic test. For comprehensive testing, install k6."
    echo ""
    
    local total_time=0
    local success_count=0
    local fail_count=0
    local iterations=100
    
    for i in $(seq 1 $iterations); do
        start=$(date +%s%N)
        if curl -sf "${API_URL}/health" > /dev/null; then
            end=$(date +%s%N)
            duration=$(( (end - start) / 1000000 )) # Convert to milliseconds
            total_time=$((total_time + duration))
            ((success_count++))
        else
            ((fail_count++))
        fi
    done
    
    if [ $success_count -gt 0 ]; then
        avg_time=$((total_time / success_count))
        echo "Results:"
        echo "  Success: ${success_count}/${iterations}"
        echo "  Failed: ${fail_count}/${iterations}"
        echo "  Average response time: ${avg_time}ms"
        
        if [ $avg_time -lt 200 ]; then
            log_info "✓ Average response time is below 200ms target"
        else
            log_error "✗ Average response time exceeds 200ms target"
        fi
    else
        log_error "All requests failed!"
        exit 1
    fi
}

# Main execution
main() {
    echo "=========================================="
    echo "Sankofa Phoenix Performance Test"
    echo "=========================================="
    echo ""
    
    if [ "$USE_K6" = true ]; then
        create_k6_script
        run_k6_test
    elif [ "$USE_AB" = true ]; then
        run_ab_test
    else
        run_curl_test
    fi
    
    echo ""
    log_info "Performance test completed!"
}

main "$@"

