<?php

function phpFpmWorkerConfigRepoRoot(): string
{
    $configuredRoot = getenv('PLENO_REPO_ROOT_FOR_TESTS');
    if (is_string($configuredRoot) && $configuredRoot !== '') {
        return rtrim($configuredRoot, DIRECTORY_SEPARATOR);
    }

    $appRoot = defined('WD') ? WD : dirname(__DIR__, 3);

    return dirname($appRoot, 3);
}

function phpFpmWorkerConfigRepoPath(string $relative): string
{
    return phpFpmWorkerConfigRepoRoot() . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $relative);
}

function phpFpmWorkerConfigValue(string $poolConfig, string $key): ?int
{
    if (!preg_match('/^' . preg_quote($key, '/') . '\s*=\s*(\d+)\s*$/m', $poolConfig, $matches)) {
        return null;
    }

    return (int)$matches[1];
}

it('configures PHP-FPM with multiple warm request workers', function (): void {
    $poolPath = phpFpmWorkerConfigRepoPath('services/php/php-fpm-pool.conf');
    expect(is_file($poolPath))->toBeTrue();

    $poolConfig = (string)file_get_contents($poolPath);

    expect($poolConfig)->toContain('[www]')
        ->and($poolConfig)->toContain('pm = dynamic')
        ->and(phpFpmWorkerConfigValue($poolConfig, 'pm.max_children'))->toBeGreaterThanOrEqual(8)
        ->and(phpFpmWorkerConfigValue($poolConfig, 'pm.start_servers'))->toBeGreaterThanOrEqual(4)
        ->and(phpFpmWorkerConfigValue($poolConfig, 'pm.min_spare_servers'))->toBeGreaterThanOrEqual(4)
        ->and(phpFpmWorkerConfigValue($poolConfig, 'pm.max_spare_servers'))->toBeGreaterThanOrEqual(8);
});

it('copies the worker pool config into every API PHP image', function (): void {
    $copyInstruction = 'COPY services/php/php-fpm-pool.conf /usr/local/etc/php-fpm.d/zz-pleno-workers.conf';
    $dockerfiles = [
        phpFpmWorkerConfigRepoPath('Dockerfile'),
        phpFpmWorkerConfigRepoPath('Dockerfile.coolify-api'),
        phpFpmWorkerConfigRepoPath('services/php/Dockerfile'),
    ];

    foreach ($dockerfiles as $dockerfile) {
        expect(is_file($dockerfile))->toBeTrue();
        expect((string)file_get_contents($dockerfile))->toContain($copyInstruction);
    }
});
