Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.ZooFlow
Imports DigitalData.Modules.Patterns
Imports DigitalData.Modules.EDMI.API
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference

Public Class ProfileSearches
    Private _LogConfig As LogConfig
    Private _Logger As Logger
    Private _Environment As Environment
    Private _Params As ClipboardWatcherParams
    Private _Client As Client

    Public Class Search
        Public Guid As Integer
        Public DataTable As DataTable
        Public TabIndex As Integer
        Public TabCaption As String
        Public ProfileId As Integer
        Public SQLCommand As String
    End Class

    Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As ClipboardWatcherParams)
        _LogConfig = LogConfig
        _Logger = LogConfig.GetLogger()
        _Environment = Environment
        _Params = Params
        Try
            If _Environment.Service.IsActive = True Then
                Try
                    Dim oSplit() As String = _Environment.Service.Address.Split(":")
                    Dim oAppServerAddress As String = oSplit(0)
                    Dim oAppServerPort As Integer = 9000
                    If oSplit.Length = 2 Then
                        oAppServerPort = oSplit(1)
                    End If
                    _Client = New Client(LogConfig, oAppServerAddress, oAppServerPort)
                    If Not IsNothing(_Client) Then
                        If _Client.Connect() Then
                            _Logger.Debug("ProfileSearches: Appserver connected successfully!")
                        End If
                    End If
                Catch ex As Exception
                    _Logger.Warn($"Could not initialize the AppServer: {ex.Message}")
                    _Logger.Error(ex)
                End Try
            End If
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Public Async Function LoadDocumentSearchesAsync(ProfileId As Integer) As Task(Of List(Of Search))
        Return Await Task.Run(Function()
                                  Return DoLoadDocumentSearches(ProfileId)
                              End Function)
    End Function

    Private Function DoLoadDocumentSearches(ProfileId As Integer) As List(Of Search)
        Dim oSQL As String = $"SELECT * FROM TBCW_PROF_DOC_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {ProfileId} ORDER BY TAB_INDEX"
        Dim oSearchesDataTable As DataTable
        If _Environment.Service.IsActive = True Then
            Dim oTableResult As TableResult = _Client.GetDatatableByName("TBCW_PROF_DOC_SEARCH", $"PROFILE_ID = {ProfileId} AND ACTIVE = 1", "TAB_INDEX")
            oSearchesDataTable = oTableResult.Table
            If oSearchesDataTable Is Nothing Then
                _Logger.Warn("TBCW_PROF_DOC_SEARCH from AppServer is nothing: Failover started...")
                oSearchesDataTable = _Environment.Database.GetDatatable(oSQL)
            End If
        Else
            oSearchesDataTable = _Environment.Database.GetDatatable(oSQL)
        End If
        Dim oDocSearches As New List(Of Search)
        If Not IsNothing(oSearchesDataTable) Then
            Dim oCounter As Integer = 0
            Dim oPatterns As New ClassPatterns(_LogConfig)

            For Each oRow As DataRow In oSearchesDataTable.Rows
                Dim oProfileId As Integer = oRow.Item("PROFILE_ID")
                Dim oTabTitle As String = oRow.Item("TAB_TITLE")
                Dim oConnectionId As Integer = oRow.Item("CONN_ID")
                Dim oGuid As Integer = oRow.Item("GUID")

                oSQL = oRow.Item("SQL_COMMAND")
                oSQL = oPatterns.ReplaceUserValues(oSQL, _Environment.User)
                oSQL = oPatterns.ReplaceInternalValues(oSQL)
                oSQL = oPatterns.ReplaceClipboardContents(oSQL, _Params.ClipboardContents)

                Dim oConnectionString = ProfileUtils.GetConnectionString(_Environment.Database, oConnectionId)

                Dim oDatatable As DataTable = _Environment.Database.GetDatatableWithConnection(oSQL, oConnectionString)

                If oDatatable Is Nothing Then
                    _Logger.Warn("Error in SQL-Query '{0}'", oSQL)
                    Continue For
                End If

                oDocSearches.Add(New Search() With {
                    .Guid = oGuid,
                    .DataTable = oDatatable,
                    .ProfileId = oProfileId,
                    .TabCaption = oTabTitle,
                    .TabIndex = oCounter,
                    .SQLCommand = oSQL
                })

                oCounter += 1
            Next
        Else


        End If


        Return oDocSearches
    End Function

    Public Async Function LoadDataSearchesAsync(ProfileId As Integer) As Task(Of List(Of Search))
        Return Await Task.Run(Function()
                                  Return DoLoadDataSearches(ProfileId)
                              End Function)
    End Function

    Private Function DoLoadDataSearches(ProfileId As Integer) As List(Of Search)
        Dim oDataSearches As New List(Of Search)

        Try
            Dim oSQL As String = $"SELECT * FROM TBCW_PROF_DATA_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {ProfileId} ORDER BY TAB_INDEX"
            Dim oSearchesDataTable As DataTable
            If _Environment.Service.IsActive = True Then
                Dim oTableResult As TableResult = _Client.GetDatatableByName("TBCW_PROF_DATA_SEARCH", $"PROFILE_ID = {ProfileId} AND ACTIVE = 1", "TAB_INDEX")
                oSearchesDataTable = oTableResult.Table
                If oSearchesDataTable Is Nothing Then
                    _Logger.Warn("TBCW_PROF_DATA_SEARCH from AppServer is nothing: Failover started...")
                    oSearchesDataTable = _Environment.Database.GetDatatable(oSQL)
                End If
            Else
                oSearchesDataTable = _Environment.Database.GetDatatable(oSQL)
            End If

            Dim oCounter As Integer = 0
            Dim oPatterns As New ClassPatterns(_LogConfig)

            For Each oRow As DataRow In oSearchesDataTable.Rows
                Try
                    Dim oProfileId As Integer = oRow.Item("PROFILE_ID")
                    Dim oTabTitle As String = oRow.Item("TAB_TITLE")
                    Dim oConnectionId As Integer = oRow.Item("CONN_ID")

                    oSQL = oRow.Item("SQL_COMMAND")
                    oSQL = oPatterns.ReplaceUserValues(oSQL, _Environment.User)
                    oSQL = oPatterns.ReplaceInternalValues(oSQL)
                    oSQL = oPatterns.ReplaceClipboardContents(oSQL, _Params.ClipboardContents)

                    Dim oConnectionString = ProfileUtils.GetConnectionString(_Environment.Database, oConnectionId)

                    Dim oDatatable As DataTable = _Environment.Database.GetDatatableWithConnection(oSQL, oConnectionString)

                    If oDatatable Is Nothing Then
                        _Logger.Warn("Error in SQL-Query '{0}'", oSQL)
                        Continue For
                    End If

                    oDataSearches.Add(New Search() With {
                        .DataTable = oDatatable,
                        .ProfileId = oProfileId,
                        .TabCaption = oTabTitle,
                        .TabIndex = oCounter,
                        .SQLCommand = oSQL
                    })

                    oCounter += 1
                Catch ex As Exception
                    _Logger.Error(ex)
                End Try
            Next

            Return oDataSearches.
                Where(Function(s) Not IsNothing(s.DataTable)).
                ToList()
        Catch ex As Exception
            _Logger.Error(ex)
            Return oDataSearches
        End Try
    End Function
End Class
