Imports NLog

Public Class Logger
    Inherits NLog.Logger
    Implements ILogger

    ''' <summary>
    ''' Optional ModuleName to create different LogFiles for different Modules (arbitrary entities, User, File, etc.)
    ''' </summary>
    ''' <returns>The current ModuleName of the logger, if any.</returns>
    Public Property ModuleName As String = Nothing

    Public Overloads Sub Info(Message As String)
        LogWithModuleName(Message, LogLevel.Info)
    End Sub

    Public Overloads Sub Warn(Message As String)
        LogWithModuleName(Message, LogLevel.Warn)
    End Sub

    Public Overloads Sub [Error](Exception As Exception)
        LogWithModuleName(Exception)
    End Sub

    Public Overloads Sub Debug(Message As String)
        LogWithModuleName(Message, LogLevel.Debug)
    End Sub

    Public Overloads Sub Trace(Message As String)
        LogWithModuleName(Message, LogLevel.Trace)
    End Sub

    Private Sub LogWithModuleName(Exception As Exception)
        Dim oEventInfo As New LogEventInfo() With {
            .Exception = Exception,
            .Level = LogLevel.Error,
            .LoggerName = Name,
            .Message = Exception.Message
        }
        oEventInfo = MaybeSetModuleName(oEventInfo)

        Log(oEventInfo)
    End Sub

    Private Sub LogWithModuleName(Message As String, LogLevel As LogLevel)
        Dim oEventInfo As New LogEventInfo(LogLevel, Name, Message)
        oEventInfo = MaybeSetModuleName(oEventInfo)

        Log(oEventInfo)
    End Sub

    Private Function MaybeSetModuleName(LogEventInfo As LogEventInfo) As LogEventInfo
        If ModuleName IsNot Nothing AndAlso ModuleName <> String.Empty Then
            LogEventInfo.Properties.Item("ModuleName") = ModuleName
        End If

        Return LogEventInfo
    End Function

    ''' <summary>
    ''' Prints a preformatted Block including a block identifier
    ''' </summary>
    ''' <param name="blockId">A unique Identifier for this block, eg. DocId, FullPath, ..</param>
    <DebuggerStepThrough()>
    Public Sub NewBlock(blockId As String)
        Dim message As String = $"-----> Start of Block {blockId}"
        Dim logEventInfo As New LogEventInfo(LogLevel.Info, Name, message)
        Dim logEventDebug As New LogEventInfo(LogLevel.Debug, Name, message)
        Dim WrapperType As Type = GetType(Logger)

        Log(WrapperType, logEventDebug)
        Log(WrapperType, logEventInfo)
    End Sub

    <DebuggerStepThrough()>
    Public Sub EndBlock()
        Dim message As String = $"<----- End of Block"
        Dim logEventInfo As New LogEventInfo(LogLevel.Info, Name, message)
        Dim logEventDebug As New LogEventInfo(LogLevel.Debug, Name, message)
        Dim WrapperType As Type = GetType(Logger)

        Log(WrapperType, logEventDebug)
        Log(WrapperType, logEventInfo)
    End Sub
End Class
