<?php

namespace Tests\Feature;

use App\Livewire\Modals\FileEditor;
use App\Models\Server;
use App\Models\User;
use App\Services\FleetService;
use App\Support\Ssh\Sftp;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use Mockery;
use Tests\TestCase;

/**
 * Binary / non-UTF-8 file content must never reach the editor's public $content property: bound into
 * Livewire's JSON snapshot, invalid UTF-8 makes json_encode fail and the client sees an empty response
 * ("undefined is not valid JSON"). The editor blanks it and shows a binary notice instead.
 */
class FileEditorBinaryTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->actingAs(User::factory()->create(['must_change_password' => false]));
        $this->app->instance(Sftp::class, Mockery::mock(Sftp::class)); // unused for text files, just resolvable
    }

    public function test_load_blanks_binary_content_to_keep_the_snapshot_valid(): void
    {
        $server = Server::create(['name' => 's', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'online']);

        $fleet = Mockery::mock(FleetService::class);
        $fleet->shouldReceive('readFile')->andReturn(['content' => "\xff\xfe\x00\x80raw-binary", 'binary' => true, 'tooBig' => false]);
        $this->app->instance(FleetService::class, $fleet);

        Livewire::test(FileEditor::class, ['serverId' => $server->id, 'path' => '/tmp/x.bin', 'name' => 'x.bin'])
            ->call('load')
            ->assertSet('binary', true)
            ->assertSet('content', '');   // raw non-UTF-8 bytes never bound to the property
    }

    public function test_load_keeps_valid_text_content(): void
    {
        $server = Server::create(['name' => 's', 'ip' => '10.0.0.9', 'ssh_port' => 22, 'status' => 'online']);

        $fleet = Mockery::mock(FleetService::class);
        $fleet->shouldReceive('readFile')->andReturn(['content' => "hello = welt\n", 'binary' => false, 'tooBig' => false]);
        $this->app->instance(FleetService::class, $fleet);

        Livewire::test(FileEditor::class, ['serverId' => $server->id, 'path' => '/etc/x.conf', 'name' => 'x.conf'])
            ->call('load')
            ->assertSet('binary', false)
            ->assertSet('content', "hello = welt\n");
    }
}
