<?php
declare(strict_types=1);

require_once __DIR__ . '/../db_bootstrap.php';
require_once __DIR__ . '/../sms_provider.php';

$conn = ensure_db(true);
$failures = [];

function sms_test_assert(bool $condition, string $label, array &$failures): void
{
    echo ($condition ? 'PASS ' : 'FAIL ') . $label . PHP_EOL;
    if (!$condition) $failures[] = $label;
}

$legacy = sms_provider_normalize_config([
    'enabled' => '1',
    'mode' => 'api',
    'api' => [
        'url' => 'https://sms.example.test/send',
        'method' => 'POST',
        'content_type' => 'form',
        'auth_type' => 'none',
        'to_param' => 'mobile',
        'text_param' => 'message',
        'sender_param' => 'from',
    ],
]);
sms_test_assert($legacy['api_url'] === 'https://sms.example.test/send', 'ترحيل رابط API من البنية القديمة', $failures);
sms_test_assert($legacy['body_type'] === 'form', 'ترحيل صيغة API من البنية القديمة', $failures);
sms_test_assert($legacy['param_map']['to'] === 'mobile' && $legacy['param_map']['text'] === 'message', 'ترحيل أسماء حقول API', $failures);

$localSender = new SmsProviderSender($conn, array_merge(sms_provider_defaults(), [
    'enabled' => '1',
    'mode' => 'local',
]));
$apiSender = new SmsProviderSender($conn, array_merge(sms_provider_defaults(), [
    'enabled' => '1',
    'mode' => 'api',
    'default_country_code' => '963',
    'api_international_numbers' => '1',
]));
sms_test_assert($localSender->normalizeTo('0932 123 456') === '0932123456', 'الإرسال المحلي يحفظ صيغة الرقم المحلي', $failures);
sms_test_assert($apiSender->normalizeTo('0932 123 456') === '963932123456', 'API يحول الرقم المحلي إلى دولي', $failures);
sms_test_assert(function_exists('sms_provider_send'), 'توفر نقطة الربط التي يستخدمها طابور الرسائل', $failures);
sms_test_assert(
    function_exists('sms_provider_windows_serial_ports')
    && function_exists('sms_provider_detect_local_modem'),
    'توفر اكتشاف منافذ COM والتحقق التلقائي من مودم الرسائل',
    $failures
);
$identifyDetails = sms_provider_parse_identify_output("Manufacturer: Example GSM\r\nModel: USB Modem\r\nIMEI: 123456789012345\r\n");
sms_test_assert(
    ($identifyDetails['Manufacturer'] ?? '') === 'Example GSM'
    && ($identifyDetails['Model'] ?? '') === 'USB Modem'
    && ($identifyDetails['IMEI'] ?? '') === '123456789012345',
    'تحليل هوية المودم المكتشف من خرج Gammu',
    $failures
);
$serialPorts = sms_provider_windows_serial_ports();
sms_test_assert(
    is_array($serialPorts)
    && array_reduce($serialPorts, static fn(bool $valid, array $port): bool => $valid
        && preg_match('/^COM[0-9]{1,3}$/', (string)($port['port'] ?? '')) === 1, true),
    'سلامة قائمة منافذ COM المكتشفة من ويندوز',
    $failures
);

$unicodeSample = 'شغوفة وهادي';
$utf8Input = sms_provider_utf8_text($unicodeSample);
sms_test_assert(
    $utf8Input === $unicodeSample
    && preg_match('//u', $utf8Input) === 1
    && !str_starts_with($utf8Input, "\xEF\xBB\xBF")
    && !str_contains($utf8Input, "\0"),
    'سلامة تمرير نص الرسالة العربية إلى Gammu بصيغة UTF-8',
    $failures
);
$preparedBatch = sms_provider_prepare_local_utf8_batch(
    'C:\\Program Files\\Gammu\\bin\\gammu.exe',
    'C:\\ProgramData\\NetworkCustomers\\gammu\\gammurc',
    '0932123456',
    $unicodeSample,
    120
);
$batchBody = (string)file_get_contents((string)$preparedBatch['batch_path']);
$batchMessage = (string)file_get_contents((string)$preparedBatch['message_path']);
sms_test_assert(
    str_contains($batchBody, 'chcp 65001 >nul')
    && str_contains($batchBody, '-unicode -text "%MSG%" -autolen 120')
    && $batchMessage === $unicodeSample
    && !str_contains($batchBody, $unicodeSample),
    'عزل النص العربي وتشغيل Gammu بصفحة UTF-8 المطابقة للإرسال اليدوي',
    $failures
);
sms_provider_cleanup_local_utf8_batch($preparedBatch);
sms_test_assert(
    !is_file((string)$preparedBatch['batch_path'])
    && !is_file((string)$preparedBatch['message_path'])
    && !is_dir((string)$preparedBatch['temp_root']),
    'تنظيف ملفات رسالة Gammu المؤقتة بعد الإرسال',
    $failures
);

$probeRoot = rtrim(sys_get_temp_dir(), '\\/') . DIRECTORY_SEPARATOR
    . 'network-customers-gammu-probe-' . bin2hex(random_bytes(4));
@mkdir($probeRoot, 0700, true);
$probePhp = $probeRoot . DIRECTORY_SEPARATOR . 'capture.php';
$probeCmd = $probeRoot . DIRECTORY_SEPARATOR . 'fake-gammu.cmd';
$probeOut = $probeRoot . DIRECTORY_SEPARATOR . 'captured.txt';
$probePhpBody = <<<'PHP'
<?php
$output = (string)($argv[1] ?? '');
$index = array_search('-text', $argv, true);
$message = is_int($index) ? (string)($argv[$index + 1] ?? '') : '';
file_put_contents($output, bin2hex($message));
PHP;
file_put_contents($probePhp, $probePhpBody);
file_put_contents(
    $probeCmd,
    "@echo off\r\n\"" . PHP_BINARY . "\" \"{$probePhp}\" \"{$probeOut}\" %*\r\nexit /b %errorlevel%\r\n"
);
$probePrepared = sms_provider_prepare_local_utf8_batch(
    $probeCmd,
    $probeRoot . DIRECTORY_SEPARATOR . 'gammurc',
    '0932123456',
    $unicodeSample,
    120
);
$probeResult = sms_provider_run_process((array)$probePrepared['command'], 10);
$capturedHex = is_file($probeOut) ? trim((string)file_get_contents($probeOut)) : '';
sms_test_assert(
    !empty($probeResult['ok']) && $capturedHex === bin2hex($unicodeSample),
    'وصول النص العربي إلى عملية Gammu بعد CP65001 دون تغيير',
    $failures
);
sms_provider_cleanup_local_utf8_batch($probePrepared);
foreach ([$probeOut, $probeCmd, $probePhp] as $probeFile) {
    if (is_file($probeFile)) @unlink($probeFile);
}
if (is_dir($probeRoot)) @rmdir($probeRoot);

$tempRoot = rtrim(sys_get_temp_dir(), '\\/') . DIRECTORY_SEPARATOR . 'network-customers-sms-test-' . bin2hex(random_bytes(4));
$configPath = $tempRoot . DIRECTORY_SEPARATOR . 'gammurc';
$managed = sms_provider_write_managed_config(array_merge(sms_provider_defaults(), [
    'local_port' => 'COM17',
    'local_connection' => 'at',
]), $configPath);
sms_test_assert(!empty($managed['ok']) && is_file($configPath), 'إنشاء ملف Gammu المدار', $failures);
$configBody = is_file($configPath) ? (string)file_get_contents($configPath) : '';
sms_test_assert(
    str_contains($configBody, 'port = COM17')
    && str_contains($configBody, 'connection = at')
    && str_contains($configBody, 'gammucoding = utf8'),
    'سلامة محتوى ملف Gammu المدار واعتماد UTF-8',
    $failures
);
sms_test_assert(
    sms_provider_default_gammu_binary() === dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'runtime' . DIRECTORY_SEPARATOR . 'gammu' . DIRECTORY_SEPARATOR . 'gammu.exe'
    && is_file(sms_provider_default_gammu_binary()),
    'اعتماد Gammu المضمّن داخل البرنامج',
    $failures
);
$legacyLocal = sms_provider_normalize_config([
    'local_gammu_path' => 'C:\\Program Files\\Gammu\\bin\\gammu.exe',
    'local_config_source' => 'existing',
    'local_config_path' => 'C:\\Users\\Legacy\\gammurc',
]);
sms_test_assert(
    $legacyLocal['local_gammu_path'] === sms_provider_default_gammu_binary()
    && $legacyLocal['local_config_source'] === 'managed'
    && $legacyLocal['local_config_path'] === sms_provider_managed_config_path(),
    'ترحيل الإعدادات القديمة تلقائياً إلى Gammu الداخلي',
    $failures
);
if (is_file($configPath)) @unlink($configPath);
if (is_dir($tempRoot)) @rmdir($tempRoot);

$invalidApi = new SmsProviderSender($conn, array_merge(sms_provider_defaults(), [
    'enabled' => '1',
    'mode' => 'api',
    'api_url' => 'not-a-url',
]));
$invalidResult = $invalidApi->sendText('0932123456', 'اختبار لا يجب إرساله');
sms_test_assert(empty($invalidResult['ok']), 'رفض إعداد API غير صالح دون محاولة إرسال', $failures);

if ($failures) {
    fwrite(STDERR, 'FAILED ' . count($failures) . ': ' . implode(' | ', $failures) . PHP_EOL);
    exit(1);
}
echo "ALL SMS PROVIDER TESTS PASSED\n";
