<?php

declare(strict_types=1);

namespace App\Framework\Logging\Handlers;

use App\Framework\Logging\LogLevel;
use App\Framework\Logging\ValueObjects\LogContext;
use App\Framework\Logging\ValueObjects\LogEntry;

/**
 * In-memory log handler for testing
 *
 * Stores all log entries in memory for inspection and assertions in tests
 */
final class InMemoryHandler implements LogHandler
{
    /** @var LogEntry[] */
    private array $entries = [];

    public function handle(LogEntry $entry): void
    {
        $this->entries[] = $entry;
    }

    /**
     * Get all logged entries
     *
     * @return LogEntry[]
     */
    public function getEntries(): array
    {
        return $this->entries;
    }

    /**
     * Get entries by log level
     *
     * @return LogEntry[]
     */
    public function getEntriesByLevel(LogLevel $level): array
    {
        return array_filter(
            $this->entries,
            fn(LogEntry $entry) => $entry->level === $level
        );
    }

    /**
     * Check if a message was logged
     */
    public function hasMessage(string $message): bool
    {
        foreach ($this->entries as $entry) {
            if (str_contains($entry->message, $message)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if a message was logged at specific level
     */
    public function hasMessageAtLevel(string $message, LogLevel $level): bool
    {
        foreach ($this->getEntriesByLevel($level) as $entry) {
            if (str_contains($entry->message, $message)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Get number of logged entries
     */
    public function count(): int
    {
        return count($this->entries);
    }

    /**
     * Get number of entries by level
     */
    public function countByLevel(LogLevel $level): int
    {
        return count($this->getEntriesByLevel($level));
    }

    /**
     * Clear all logged entries
     */
    public function clear(): void
    {
        $this->entries = [];
    }
}
