<?php

declare(strict_types=1);

/**
 * @return array<int, array{path:string, classification:string, type:string, reason?:string}>
 */
function legacy_test_manifest(): array
{
    return require app_path('tests/Support/legacy_test_manifest.php');
}

/**
 * @param array{path:string, classification:string, type:string, bootstrap?:string} $entry
 * @return array{exitCode:int, output:string}
 */
function run_legacy_manifest_entry(array $entry): array
{
    $path = app_path($entry['path']);
    $php = escapeshellarg(PHP_BINARY);

    if ($entry['type'] === 'phpunit') {
        $command = $php
            . ' ' . escapeshellarg(app_path('vendor/bin/phpunit'))
            . ' --bootstrap ' . escapeshellarg(app_path('tests/Support/legacy_bootstrap.php'))
            . ' ' . escapeshellarg($path)
            . ' 2>&1';
    } else {
        $bootstrap = $entry['bootstrap'] ?? 'app';
        $command = $php
            . ' ' . escapeshellarg(app_path('tests/Support/run_legacy_script.php'))
            . ' ' . escapeshellarg($entry['path'])
            . ' ' . escapeshellarg($bootstrap)
            . ' 2>&1';
    }

    $lines = [];
    $exitCode = 0;
    exec($command, $lines, $exitCode);

    return [
        'exitCode' => $exitCode,
        'output' => implode(PHP_EOL, $lines),
    ];
}

foreach (legacy_test_manifest() as $entry) {
    it('runs legacy PHP test ' . $entry['path'], function () use ($entry): void {
        if ($entry['classification'] === 'manual-external') {
            test()->markTestSkipped($entry['reason'] ?? 'Legacy test requires an external dependency.');
        }

        if (getenv('RUN_LEGACY_TESTS') !== '1') {
            test()->markTestSkipped('Set RUN_LEGACY_TESTS=1 to run legacy PHP tests.');
        }

        $result = run_legacy_manifest_entry($entry);

        expect($result['exitCode'])->toBe(
            0,
            'Legacy test failed: ' . $entry['path'] . PHP_EOL . $result['output']
        );
    })->group('legacy', $entry['classification']);
}
