Imports DigitalData.Modules.Logging
Imports System.Text.RegularExpressions

Namespace Modules
    Public Class BaseModule
        Friend ReadOnly Logger As Logger
        Private ReadOnly MyRegex As Regex = New Regex("{#(\w+)#([\:\.\w\s_/-]+)}+")
        Private ReadOnly SqlPhrases As New List(Of String) From {
            "SELECT ", "UPDATE ", "DELETE ", "EXEC "
        }

        Private Const MAX_TRY_COUNT = 500

        Public Sub New(pLogConfig As LogConfig)
            Logger = pLogConfig.GetLogger()
        End Sub

        Public Sub IncrementCounterOrThrow(ByRef pCounter As Integer)
            If pCounter >= MAX_TRY_COUNT Then
                Throw New OverflowException("Max tries exceeded while replacing placeholders!")
            End If

            pCounter += 1
        End Sub

        Public Function ReplacePattern(pInput As String, pType As String, pReplacement As String) As String
            Dim oElements As MatchCollection = MyRegex.Matches(pInput)

            If IsNothing(pReplacement) Then
                Return pInput
            End If

            Dim oIsSQL As Boolean = False
            For Each oPhrase In SqlPhrases
                If pInput.Contains(oPhrase) Then
                    oIsSQL = True
                    Exit For
                End If
            Next

            If oIsSQL = True Then
                Logger.Debug("Input string is most likely an SQL Query, masking quotes in replacement string.")
                pReplacement = pReplacement.Replace("'", "''")
            End If

            For Each oElement As Match In oElements
                ' if group 1 contains the 'pattern' the replace whole group with 'replacement'
                ' and return it
                If oElement.Groups(1).Value = pType Then
                    Logger.Debug("Replacing Placeholder with [{0}]", pReplacement)
                    Return Regex.Replace(pInput, oElement.Groups(0).Value, pReplacement)
                End If
            Next

            ' no replacement made
            Return pInput
        End Function

        Public Function ContainsPatternAndValue(pInput As String, pType As String, pValue As String) As Boolean
            Dim oElements As MatchCollection = MyRegex.Matches(pInput)

            For Each oElement As Match In oElements
                ' Pattern in pInput
                Dim oType As String = oElement.Groups(1).Value
                Dim oValue As String = oElement.Groups(2).Value

                If oType = pType And oValue = pValue Then
                    Return True
                End If
            Next

            Return False
        End Function

        Public Function ContainsPattern(pInput As String, pType As String) As String
            Dim oElements As MatchCollection = MyRegex.Matches(pInput)

            For Each oElement As Match In oElements
                Dim t As String = oElement.Groups(1).Value

                If t = pType Then
                    Return True
                End If
            Next

            Return False
        End Function

        Public Function HasPattern(pInput As String, pType As String) As Boolean
            Dim oMatches = MyRegex.Matches(pInput)

            For Each oMatch As Match In oMatches
                For Each oGroup As Group In oMatch.Groups
                    If oGroup.Value = pType Then
                        Return True
                    End If
                Next
            Next

            Return False
        End Function

        Public Function GetNextPattern(pInput As String, pType As String) As Pattern
            Dim oElements As MatchCollection = MyRegex.Matches(pInput)

            For Each oElement As Match In oElements
                ' Pattern in pInput
                Dim oType As String = oElement.Groups(1).Value
                Dim oValue As String = oElement.Groups(2).Value

                If oType = pType Then
                    Return New Pattern(oType, oValue)
                End If
            Next

            Return Nothing
        End Function
    End Class
End Namespace
