<commit_before>﻿using System;

namespace RockLib.Logging.AspNetCore
{
    /// <summary>
    /// Wrap RockLib's Logger in a Microsoft.Extensions.Logging's interface <see cref="Microsoft.Extensions.Logging.ILogger"/>.
    /// </summary>
    internal class RockLibLogger : Microsoft.Extensions.Logging.ILogger
    {
        private readonly ILogger _logger;
        private readonly string _categoryName;

        public RockLibLogger(ILogger logger, string categoryName)
        {
            _logger = logger;
            _categoryName = categoryName;
        }

        public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId,
            TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (formatter == null)
                throw new ArgumentNullException(nameof(formatter));
            
            var convertLogLevel = ConvertLogLevel(logLevel);
            if (!IsEnabled(convertLogLevel))
                return;

            var logEntry = new LogEntry(formatter(state, exception), exception, convertLogLevel);
            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.EventId"] = eventId;
            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.State"] = state;
            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.CategoryName"] = _categoryName;

            _logger.Log(logEntry);
        }

        public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel)
        {
            // We do not have a concept of logging level none, so just return.
            if (logLevel == Microsoft.Extensions.Logging.LogLevel.None)
                return false;

            var convertLogLevel = ConvertLogLevel(logLevel);
            return IsEnabled(convertLogLevel);
        }

        private bool IsEnabled(LogLevel logLevel)
        {
            return _logger.IsEnabled(logLevel);
        }

        /// <summary>
        /// Convert loglevel to RockLib variant.
        /// </summary>
        /// <param name="logLevel">level to be converted.</param>
        /// <returns></returns>
        private static LogLevel ConvertLogLevel(Microsoft.Extensions.Logging.LogLevel logLevel)
        {
            switch (logLevel)
            {
                case Microsoft.Extensions.Logging.LogLevel.Trace:
                    return LogLevel.Debug;
                case Microsoft.Extensions.Logging.LogLevel.Debug:
                    return LogLevel.Debug;
                case Microsoft.Extensions.Logging.LogLevel.Information:
                    return LogLevel.Info;
                case Microsoft.Extensions.Logging.LogLevel.Warning:
                    return LogLevel.Warn;
                case Microsoft.Extensions.Logging.LogLevel.Error:
                    return LogLevel.Error;
                case Microsoft.Extensions.Logging.LogLevel.Critical:
                    return LogLevel.Fatal;
                default:
                    return LogLevel.NotSet;
            }
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            // TODO: Implement scope at some point.
            return null;
        }
    }
}<commit_msg>Implement BeginScope in RockLibLogger<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace RockLib.Logging.AspNetCore
{
    /// <summary>
    /// Wrap RockLib's Logger in a Microsoft.Extensions.Logging's interface <see cref="Microsoft.Extensions.Logging.ILogger"/>.
    /// </summary>
    internal class RockLibLogger : Microsoft.Extensions.Logging.ILogger
    {
        private readonly ILogger _logger;
        private readonly string _categoryName;
        private readonly Lazy<Stack<object>> _scope = new Lazy<Stack<object>>(() => new Stack<object>());

        public RockLibLogger(ILogger logger, string categoryName)
        {
            _logger = logger;
            _categoryName = categoryName;
        }

        public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId,
            TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (formatter == null)
                throw new ArgumentNullException(nameof(formatter));
            
            var convertLogLevel = ConvertLogLevel(logLevel);
            if (!IsEnabled(convertLogLevel))
                return;

            var logEntry = new LogEntry(formatter(state, exception), exception, convertLogLevel);

            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.EventId"] = eventId;
            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.State"] = state;
            logEntry.ExtendedProperties["Microsoft.Extensions.Logging.CategoryName"] = _categoryName;

            if (_scope.IsValueCreated)
                logEntry.ExtendedProperties["Microsoft.Extensions.Logging.Scope"] = _scope.Value;

            _logger.Log(logEntry);
        }

        public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel)
        {
            // We do not have a concept of logging level none, so just return.
            if (logLevel == Microsoft.Extensions.Logging.LogLevel.None)
                return false;

            var convertLogLevel = ConvertLogLevel(logLevel);
            return IsEnabled(convertLogLevel);
        }

        private bool IsEnabled(LogLevel logLevel)
        {
            return _logger.IsEnabled(logLevel);
        }

        /// <summary>
        /// Convert loglevel to RockLib variant.
        /// </summary>
        /// <param name="logLevel">level to be converted.</param>
        /// <returns></returns>
        private static LogLevel ConvertLogLevel(Microsoft.Extensions.Logging.LogLevel logLevel)
        {
            switch (logLevel)
            {
                case Microsoft.Extensions.Logging.LogLevel.Trace:
                    return LogLevel.Debug;
                case Microsoft.Extensions.Logging.LogLevel.Debug:
                    return LogLevel.Debug;
                case Microsoft.Extensions.Logging.LogLevel.Information:
                    return LogLevel.Info;
                case Microsoft.Extensions.Logging.LogLevel.Warning:
                    return LogLevel.Warn;
                case Microsoft.Extensions.Logging.LogLevel.Error:
                    return LogLevel.Error;
                case Microsoft.Extensions.Logging.LogLevel.Critical:
                    return LogLevel.Fatal;
                default:
                    return LogLevel.NotSet;
            }
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            _scope.Value.Push(state);
            return new DisposeScope(_scope.Value);
        }

        private class DisposeScope : IDisposable
        {
            private readonly Stack<object> _scope;
            public DisposeScope(Stack<object> scope) => _scope = scope;
            public void Dispose() => _scope.Pop();
        }
    }
}
{'fraction_non_alphanumeric': 0.08649490373725935, 'fraction_numerical': 0.0, 'mean_word_length': 1.9709840201850295, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4812695', 'n_tokens_mistral': 1758, 'n_tokens_neox': 1684, 'n_words': 368}