#!/usr/bin/env php
<?php
// test-suite.php
// Comprehensive test suite for the MerchantsOfHope.org platform

echo "=== MerchantsOfHope.org Platform Test Suite ===\n\n";

// Configuration
// When running inside container, use nginx service on port 80
// When running from host, use localhost:20001
$baseUrl = getenv('TEST_BASE_URL') ?: 'http://nginx'; // Default to container-to-container communication
$tests = [];

// Test functions
function makeRequest($url, $method = 'GET', $data = null) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    
    if ($data && ($method === 'POST' || $method === 'PUT')) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen(json_encode($data))
        ]);
    }
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    curl_close($ch);
    
    return [
        'statusCode' => $httpCode,
        'body' => $response,
        'contentType' => $contentType
    ];
}

function assertTrue($condition, $message) {
    if (!$condition) {
        throw new Exception("Assertion failed: $message");
    }
}

function assertFalse($condition, $message) {
    if ($condition) {
        throw new Exception("Assertion failed: $message");
    }
}

function assertEquals($expected, $actual, $message) {
    if ($expected !== $actual) {
        throw new Exception("Assertion failed: $message. Expected: $expected, Got: $actual");
    }
}

function assertContains($needle, $haystack, $message) {
    if (strpos($haystack, $needle) === false) {
        throw new Exception("Assertion failed: $message. Needle: $needle, Haystack: " . substr($haystack, 0, 200) . "...");
    }
}

function runTest($name, $callback) {
    global $tests;
    
    echo "Running test: $name... ";
    
    try {
        $callback();
        echo "✓ PASSED\n";
        $tests[] = ['name' => $name, 'status' => 'PASSED'];
    } catch (Exception $e) {
        echo "✗ FAILED: " . $e->getMessage() . "\n";
        $tests[] = ['name' => $name, 'status' => 'FAILED', 'error' => $e->getMessage()];
    }
}

// Test cases
runTest('Homepage loads successfully', function() use ($baseUrl) {
    $response = makeRequest($baseUrl . '/');
    assertEquals(200, $response['statusCode'], 'Expected HTTP 200 status code');
    assertContains('<html', $response['body'], 'Expected HTML response');
    assertContains('MerchantsOfHope.org', $response['body'], 'Expected site title in response');
});

runTest('Health endpoint returns OK status', function() use ($baseUrl) {
    $response = makeRequest($baseUrl . '/health');
    assertEquals(200, $response['statusCode'], 'Expected HTTP 200 status code');
    assertContains('application/json', $response['contentType'], 'Expected JSON response');
    
    $data = json_decode($response['body'], true);
    assertTrue($data !== null, 'Expected valid JSON response');
    assertTrue(isset($data['status']), 'Expected status field in response');
    assertEquals('ok', $data['status'], 'Expected status to be "ok"');
});

runTest('Positions endpoint returns job listings', function() use ($baseUrl) {
    $response = makeRequest($baseUrl . '/positions');
    assertEquals(200, $response['statusCode'], 'Expected HTTP 200 status code');
    assertContains('application/json', $response['contentType'], 'Expected JSON response');
    
    $data = json_decode($response['body'], true);
    assertTrue($data !== null, 'Expected valid JSON response');
    assertTrue(isset($data['positions']), 'Expected positions field in response');
    assertTrue(is_array($data['positions']), 'Expected positions to be an array');
});

runTest('Authentication endpoint accepts login requests', function() use ($baseUrl) {
    $response = makeRequest($baseUrl . '/auth/login', 'POST', [
        'email' => 'test@example.com',
        'password' => 'password123'
    ]);
    
    // Even if authentication fails, the endpoint should respond properly
    assertTrue(in_array($response['statusCode'], [200, 400, 401]), 'Expected valid HTTP status code');
    assertContains('application/json', $response['contentType'], 'Expected JSON response');
});

runTest('Job creation endpoint handles requests', function() use ($baseUrl) {
    $response = makeRequest($baseUrl . '/positions', 'POST', [
        'title' => 'Test Position',
        'description' => 'Test description'
    ]);
    
    // Should handle the request properly even if authentication is required
    assertTrue(in_array($response['statusCode'], [200, 400, 401, 403]), 'Expected valid HTTP status code');
    assertContains('application/json', $response['contentType'], 'Expected JSON response');
});

// Summary
echo "\n=== Test Summary ===\n";
$passed = 0;
$failed = 0;

foreach ($tests as $test) {
    if ($test['status'] === 'PASSED') {
        $passed++;
    } else {
        $failed++;
    }
}

echo "Passed: $passed\n";
echo "Failed: $failed\n";
echo "Total: " . count($tests) . "\n";

if ($failed > 0) {
    echo "\nFailed tests:\n";
    foreach ($tests as $test) {
        if ($test['status'] === 'FAILED') {
            echo "- {$test['name']}: {$test['error']}\n";
        }
    }
    exit(1);
} else {
    echo "\n✓ All tests passed!\n";
    exit(0);
}