<?php

namespace Acms\Services\SiteSeed\Logger;

use Acms\Services\SiteSeed\Contracts\SiteSeedLogger;
use Throwable;

/**
 * テスト / 非対話実行向け: すべてのログを配列に蓄積するだけの Logger
 *
 * @phpstan-type LogRecord array{level: string, message: string, stage?: string, current?: int, total?: int, exception?: \Throwable|null}
 */
final class CollectingSiteSeedLogger implements SiteSeedLogger
{
    /** @var list<array<string, mixed>> */
    private array $records = [];

    public function info(string $message): void
    {
        $this->records[] = ['level' => 'info', 'message' => $message];
    }

    public function progress(string $stage, int $current, int $total): void
    {
        $this->records[] = [
            'level' => 'progress',
            'message' => sprintf('%s: %d/%d', $stage, $current, $total),
            'stage' => $stage,
            'current' => $current,
            'total' => $total,
        ];
    }

    public function warning(string $message): void
    {
        $this->records[] = ['level' => 'warning', 'message' => $message];
    }

    public function error(string $message, ?Throwable $e = null): void
    {
        $this->records[] = [
            'level' => 'error',
            'message' => $message,
            'exception' => $e,
        ];
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function records(): array
    {
        return $this->records;
    }

    /**
     * @return list<string>
     */
    public function messages(): array
    {
        return array_map(
            static fn (array $r): string => (string) $r['message'],
            $this->records
        );
    }
}
