Imports System.ServiceModel
Imports System.Xml
Imports DigitalData.Modules.Base
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports DigitalData.Modules.Logging

Public Class Channel
    Inherits BaseClass

    Private ReadOnly ChannelFactory As ChannelFactory(Of IEDMIServiceChannel)

    Public Event Reconnect As EventHandler

    Public Shared Function GetBinding(Optional AuthenticationMode As TcpClientCredentialType = TcpClientCredentialType.Windows) As NetTcpBinding
        Return New NetTcpBinding() With {
            .MaxReceivedMessageSize = Constants.ChannelSettings.MAX_RECEIVED_MESSAGE_SIZE,
            .MaxBufferSize = Constants.ChannelSettings.MAX_BUFFER_SIZE,
            .MaxBufferPoolSize = Constants.ChannelSettings.MAX_BUFFER_POOL_SIZE,
            .TransferMode = TransferMode.Streamed,
            .Security = New NetTcpSecurity() With {
                .Mode = SecurityMode.Transport,
                .Transport = New TcpTransportSecurity() With {
                    .ClientCredentialType = AuthenticationMode
                }
            },
            .ReaderQuotas = New XmlDictionaryReaderQuotas() With {
                .MaxArrayLength = Constants.ChannelSettings.MAX_ARRAY_LENGTH,
                .MaxStringContentLength = Constants.ChannelSettings.MAX_STRING_CONTENT_LENGTH
            }
        }
    End Function

    Public Sub New(pLogConfig As LogConfig, pServerAddress As ServerAddressStruct)
        MyBase.New(pLogConfig)
        ChannelFactory = GetChannelFactory(pServerAddress)
    End Sub

    ''' <summary>
    ''' Creates a channel and adds a Faulted-Handler
    ''' </summary>
    ''' <returns>A channel object</returns>
    Public Function GetChannel() As IEDMIServiceChannel
        Try
            Logger.Debug("Creating channel.")
            Dim oChannel = ChannelFactory.CreateChannel()

            AddHandler oChannel.Faulted, Sub() RaiseEvent Reconnect(Me, Nothing)

            Return oChannel
        Catch ex As Exception
            Logger.Error(ex)
            Throw ex
        End Try
    End Function

    Private Function GetChannelFactory(pServerAddress As ServerAddressStruct) As ChannelFactory(Of IEDMIServiceChannel)
        Dim oBinding = GetBinding()
        Dim oAddress = New EndpointAddress($"net.tcp://{pServerAddress.Host}:{pServerAddress.Port}/DigitalData/Services/Main")
        Dim oFactory = New ChannelFactory(Of IEDMIServiceChannel)(oBinding, oAddress)
        Return oFactory
    End Function
End Class


