<?php

namespace Tests\Unit;

use App\Services\FleetService;
use ReflectionMethod;
use Tests\TestCase;

/**
 * The journal poll resumes from the journald cursor that `--show-cursor` appends as a
 * trailing `-- cursor: X` line. These cover the two pure helpers that make that work.
 */
class JournalCursorTest extends TestCase
{
    private function invokePrivate(string $method, string $body)
    {
        $m = new ReflectionMethod(FleetService::class, $method);
        $m->setAccessible(true);

        return $m->invoke(app(FleetService::class), $body);
    }

    public function test_split_pulls_the_trailing_cursor_off_the_body(): void
    {
        $body = "2026-06-14T10:00:01+02:00 host nginx[1]: started\n-- cursor: s=abc123;i=4f;b=9";

        [$kept, $cursor] = $this->invokePrivate('splitJournalCursor', $body);

        $this->assertSame('s=abc123;i=4f;b=9', $cursor);
        $this->assertStringNotContainsString('-- cursor:', $kept);
        $this->assertStringContainsString('nginx[1]: started', $kept);
    }

    public function test_split_returns_null_cursor_when_absent(): void
    {
        [, $cursor] = $this->invokePrivate('splitJournalCursor', '2026-06-14T10:00:01+02:00 host nginx[1]: started');

        $this->assertNull($cursor);
    }

    public function test_parse_lines_classifies_levels_and_never_injects_a_placeholder(): void
    {
        $body = implode("\n", [
            '2026-06-14T10:00:01+02:00 host nginx[1]: connection refused',
            '2026-06-14T10:00:02+02:00 host cron[9]: warning clock skew detected',
            '2026-06-14T10:00:03+02:00 host sshd[7]: accepted publickey',
        ]);

        $rows = $this->invokePrivate('parseJournalLines', $body);

        $this->assertCount(3, $rows);
        $this->assertSame('error', $rows[0]['level']);
        $this->assertSame('warn', $rows[1]['level']);
        $this->assertSame('info', $rows[2]['level']);
        $this->assertSame('2026-06-14 10:00:01', $rows[0]['time']);
    }

    public function test_parse_lines_on_empty_input_returns_empty_no_placeholder(): void
    {
        // Empty = "nothing new since the cursor", which must NOT look like a permission error.
        $this->assertSame([], $this->invokePrivate('parseJournalLines', ''));
        $this->assertSame([], $this->invokePrivate('parseJournalLines', '-- No entries --'));
    }
}
