<?php

use App\Livewire\Admin\Readiness;
use App\Services\Deployment\UpdateChannel;
use Illuminate\Support\Facades\File;
use Livewire\Livewire;

/** Was deploy/update-agent.sh bei jedem Tick schreibt — sein Lebenszeichen. */
function agentIsAlive(): void
{
    File::ensureDirectoryExists(storage_path('app/deploy'));
    File::put(
        storage_path('app/deploy/update-status.json'),
        json_encode(['checked_at' => now()->toIso8601String()])
    );
}

/**
 * Die zwei Betriebspunkte sind keine Einstellungen: „läuft der Zeitplaner",
 * „läuft der Bereitstellungs-Worker". Zu stellen gibt es nichts — die Kur ist
 * ein Neustart, und den konnte die Konsole längst anfordern, nur nicht von
 * dieser Seite aus. Der „Beheben"-Link zeigte auf den Roheditor der .env, wo
 * nichts steht, das hilft.
 */
beforeEach(function () {
    // Dieselbe geteilte storage/app/deploy-Ablage wie UpdateButtonTest und
    // IntegrationsPageTest: Pest fährt alle Dateien in EINEM Prozess, ein
    // Rest aus dem zuvor gelaufenen entschiede sonst, ob der Agent hier als
    // lebendig gilt.
    File::deleteDirectory(storage_path('app/deploy'));
});

it('asks the agent to restart the workers', function () {
    // Der Agent muss sich gemeldet haben, sonst nimmt der Kanal nichts an.
    agentIsAlive();

    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(Readiness::class)
        ->call('restartWorkers')
        ->assertHasNoErrors();

    expect(app(UpdateChannel::class)->state()['requested_at'])->not->toBeNull();
});

it('says so honestly when no agent is there to hear it', function () {
    // Kein Herzschlag: die Anfrage landet in einer Datei, die niemand liest.
    // Ein „wird neu gestartet" wäre hier genau die zuversichtliche Anzeige
    // über der roten Grundlage, die dieses Projekt wiederholt gekostet hat.
    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(Readiness::class)
        ->call('restartWorkers')
        ->assertDispatched('notify', message: __('readiness.restart_no_agent'));

    expect(app(UpdateChannel::class)->state()['requested_at'])->toBeNull();
});

it('does not let an operator without the capability reach the page at all', function () {
    // `Support` hat weder hosts.manage noch secrets.manage und wird schon in
    // mount() abgewiesen — die Aktion selbst prüft hosts.manage noch einmal
    // (siehe restartWorkers), weil eine Berechtigung, die nur die Seite
    // bewacht, keine ist.
    agentIsAlive();

    Livewire::actingAs(operator('Support'), 'operator')
        ->test(Readiness::class)
        ->assertForbidden();

    expect(app(UpdateChannel::class)->state()['requested_at'])->toBeNull();
});

it('offers the button on the two heartbeat entries', function () {
    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(Readiness::class)
        ->assertSee(__('readiness.restart_workers'));
});
