<?php

app_require('classes/shelly.php');

use classes\shelly;

class ShellyRealRequestGuardHarness extends shelly
{
    public function __construct()
    {
    }
}

function restore_shelly_guard_env_for_test(string $key, string|false $previous): void
{
    if ($previous === false) {
        putenv($key);
        unset($_ENV[$key], $_SERVER[$key]);
        return;
    }

    putenv($key . '=' . $previous);
    $_ENV[$key] = $previous;
    $_SERVER[$key] = $previous;
}

it('blocks and records test-mode Shelly POST requests before cURL can run', function (): void {
    $previousBlock = getenv('TRUCKWASH_TEST_BLOCK_REAL_SHELLY');
    $previousLog = getenv('TRUCKWASH_TEST_SHELLY_GUARD_LOG');
    $logPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'truckwash-shelly-guard-post-' . uniqid('', true) . '.jsonl';

    try {
        putenv('TRUCKWASH_TEST_BLOCK_REAL_SHELLY=1');
        putenv('TRUCKWASH_TEST_SHELLY_GUARD_LOG=' . $logPath);
        shelly::resetBlockedRequestLog();

        $client = new ShellyRealRequestGuardHarness();

        expect(fn() => $client->sendPostRequest('/v2/devices/api/set/switch', [
            'id' => 'real-relay',
            'on' => true,
        ]))->toThrow(Exception::class, 'Real Shelly requests are blocked in test mode');

        $entries = shelly::blockedRequestLog();
        expect($entries)->toHaveCount(1)
            ->and($entries[0]['method'])->toBe('POST')
            ->and($entries[0]['endpoint'])->toBe('/v2/devices/api/set/switch')
            ->and($entries[0]['data'])->toMatchArray(['id' => 'real-relay', 'on' => true]);

        $logLines = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        expect($logLines)->not->toBeFalse();
        $logged = json_decode((string)$logLines[0], true);
        expect($logged)->toMatchArray([
            'method' => 'POST',
            'endpoint' => '/v2/devices/api/set/switch',
        ]);
    } finally {
        shelly::resetBlockedRequestLog();
        @unlink($logPath);
        restore_shelly_guard_env_for_test('TRUCKWASH_TEST_BLOCK_REAL_SHELLY', $previousBlock);
        restore_shelly_guard_env_for_test('TRUCKWASH_TEST_SHELLY_GUARD_LOG', $previousLog);
    }
});

it('blocks and records test-mode Shelly GET requests before cURL can run', function (): void {
    $previousBlock = getenv('TRUCKWASH_TEST_BLOCK_REAL_SHELLY');
    $previousLog = getenv('TRUCKWASH_TEST_SHELLY_GUARD_LOG');
    $logPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'truckwash-shelly-guard-get-' . uniqid('', true) . '.jsonl';

    try {
        putenv('TRUCKWASH_TEST_BLOCK_REAL_SHELLY=1');
        putenv('TRUCKWASH_TEST_SHELLY_GUARD_LOG=' . $logPath);
        shelly::resetBlockedRequestLog();

        $client = new ShellyRealRequestGuardHarness();

        expect(fn() => $client->sendGetRequest('/device/all_status', [
            'show_info' => 'true',
        ]))->toThrow(Exception::class, 'Real Shelly requests are blocked in test mode');

        $entries = shelly::blockedRequestLog();
        expect($entries)->toHaveCount(1)
            ->and($entries[0]['method'])->toBe('GET')
            ->and($entries[0]['endpoint'])->toBe('/device/all_status')
            ->and($entries[0]['data'])->toMatchArray(['show_info' => 'true']);
    } finally {
        shelly::resetBlockedRequestLog();
        @unlink($logPath);
        restore_shelly_guard_env_for_test('TRUCKWASH_TEST_BLOCK_REAL_SHELLY', $previousBlock);
        restore_shelly_guard_env_for_test('TRUCKWASH_TEST_SHELLY_GUARD_LOG', $previousLog);
    }
});
