using System.Collections.Concurrent;

namespace LazyBear.MCP.Services.Logging;

/// <summary>
/// Singleton, хранящий последние <see cref="Capacity"/> записей лога в памяти.
/// Безопасен для многопоточной записи.
/// </summary>
public sealed class InMemoryLogSink
{
    public const int Capacity = 500;

    private readonly ConcurrentQueue<LogEntry> _entries = new();

    /// <summary>Событие вызывается при добавлении новой записи.</summary>
    public event Action<LogEntry>? OnLog;

    public void Add(LogEntry entry)
    {
        _entries.Enqueue(entry);

        // Обрезаем старые записи
        while (_entries.Count > Capacity)
        {
            _entries.TryDequeue(out _);
        }

        OnLog?.Invoke(entry);
    }

    /// <summary>
    /// Возвращает снимок всех записей. Опциональный фильтр по категории-префиксу.
    /// </summary>
    public IReadOnlyList<LogEntry> GetEntries(string? categoryPrefix = null)
    {
        var all = _entries.ToArray();

        if (string.IsNullOrWhiteSpace(categoryPrefix))
        {
            return all;
        }

        return Array.FindAll(all, e => e.Category.StartsWith(categoryPrefix, StringComparison.OrdinalIgnoreCase));
    }

    public void Clear() => _entries.Clear();
}
