using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;

namespace StellaOps.Feedser.Merge.Tests;

internal sealed class TestLogger<T> : ILogger<T>
{
    private static readonly IDisposable NoopScope = new DisposableScope();

    public List<LogEntry> Entries { get; } = new();

    public IDisposable BeginScope<TState>(TState state)
        where TState : notnull
        => NoopScope;

    public bool IsEnabled(LogLevel logLevel) => true;

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
    {
        if (formatter is null)
        {
            throw new ArgumentNullException(nameof(formatter));
        }

        IReadOnlyList<KeyValuePair<string, object?>>? structuredState = null;
        if (state is IReadOnlyList<KeyValuePair<string, object?>> list)
        {
            structuredState = list.ToArray();
        }
        else if (state is IEnumerable<KeyValuePair<string, object?>> enumerable)
        {
            structuredState = enumerable.ToArray();
        }

        Entries.Add(new LogEntry(logLevel, eventId, formatter(state, exception), structuredState));
    }

    internal sealed record LogEntry(
        LogLevel Level,
        EventId EventId,
        string Message,
        IReadOnlyList<KeyValuePair<string, object?>>? StructuredState);

    private sealed class DisposableScope : IDisposable
    {
        public void Dispose()
        {
        }
    }
}
