Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports System.ServiceModel
Imports System.IO

Public Class Document
    Private _logger As Logger
    Private _logConfig As LogConfig
    Private _channelFactory As ChannelFactory(Of IEDMIServiceChannel)
    Private _channel As IEDMIServiceChannel

    ''' <summary>
    ''' Creates a new EDMIAPI object
    ''' </summary>
    ''' <param name="LogConfig">LogConfig object</param>
    ''' <param name="ServiceAdress">The full service url to connect to</param>
    Public Sub New(LogConfig As LogConfig, ServiceAdress As String)
        _logger = LogConfig.GetLogger()
        _logConfig = LogConfig

        Try
            Dim oBinding = Channel.GetBinding()
            Dim oAddress = New EndpointAddress(ServiceAdress)
            Dim oFactory = New ChannelFactory(Of IEDMIServiceChannel)(oBinding, oAddress)

            _channelFactory = oFactory
        Catch ex As Exception
            _logger.Error(ex)
        End Try
    End Sub

    ''' <summary>
    ''' Connect to the service
    ''' </summary>
    ''' <returns>True if connection was successful, false otherwise</returns>
    Public Function Connect() As Boolean
        Try
            _channel = GetChannel()

            _logger.Debug("Opening channel..")
            _channel.Open()

            _logger.Info("Connection to Service established!")
            Return True
        Catch ex As Exception
            _logger.Error(ex)
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Imports a file by filename
    ''' </summary>
    ''' <param name="FilePath">The filename to import</param>
    ''' <returns>A document object</returns>
    Public Async Function ImportFileAsync(FilePath As String, Optional [ReadOnly] As Boolean = False, Optional RetentionPeriod As Integer = 0) As Task(Of DocumentResult)
        Try
            Using oStream As New FileStream(FilePath, FileMode.Open)
                Dim oContents As Byte() = {}
                Dim oBytesRead = Await oStream.ReadAsync(oContents, 0, oStream.Length)
                Dim oResult = Await _channel.ImportFileAsync(FilePath, oContents, Environment.UserName)

                Return oResult
            End Using
        Catch ex As Exception
            _logger.Error(ex)
            Throw ex
        End Try
    End Function

    ''' <summary>
    ''' Imports a file by filename
    ''' </summary>
    ''' <param name="FilePath">The filename to import</param>
    ''' <returns>A document object</returns>
    Public Function ImportFile(FilePath As String) As DocumentResult
        Try
            Dim oContents As Byte() = File.ReadAllBytes(FilePath)
            Dim oInfo As New FileInfo(FilePath)
            Dim oDocObject = _channel.ImportFile(FilePath, oContents, Environment.UserName)
            Return oDocObject
        Catch ex As Exception
            _logger.Error(ex)
            Throw ex
        End Try
    End Function

    '''' <summary>
    '''' Imports a file by filename
    '''' </summary>
    '''' <param name="FilePath">The filename to import</param>
    '''' <returns>A document object</returns>
    'Public Function ImportFile(FilePath As String) As DocumentResult
    '    Try
    '        Dim oContents As Byte() = File.ReadAllBytes(FilePath)
    '        Dim oInfo As New FileInfo(FilePath)
    '        Dim oName As String = oInfo.Name
    '        Dim oExtension As String = oInfo.Extension.Substring(1)

    '        Dim oDocObject = _channel.NewFile(oName, oContents)
    '        Return oDocObject
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    '''' <summary>
    '''' Imports a file by filename
    '''' </summary>
    '''' <param name="FilePath">The filename to import</param>
    '''' <returns>A document object</returns>
    'Public Async Function ImportFileAsync(FilePath As String) As Task(Of DocumentResult)
    '    Try
    '        Dim oContents As Byte() = File.ReadAllBytes(FilePath)
    '        Dim oInfo As New FileInfo(FilePath)
    '        Dim oName As String = oInfo.Name
    '        Dim oExtension As String = oInfo.Extension.Substring(1)

    '        Dim oDocObject = Await _channel.NewFileAsync(oName, oContents)
    '        Return oDocObject
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    'Public Async Function NewFileIndexAsync(DocObject As DocumentObject, Syskey As String, LanguageCode As String, Value As String) As Task(Of IndexResult)
    '    Try
    '        Dim oResult As IndexResult = Await _channel.NewFileIndexAsync(DocObject, Syskey, LanguageCode, Value)

    '        Return oResult
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    'Public Function NewFileIndex(DocObject As DocumentObject, Syskey As String, LanguageCode As String, Value As String) As IndexResult
    '    Try
    '        Dim oResult As IndexResult = _channel.NewFileIndex(DocObject, Syskey, LanguageCode, Value)

    '        Return oResult
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    'Public Function GetDocumentByDocumentId(DocumentId As Int64) As DocumentResult
    '    Try
    '        Return _channel.GetDocumentByDocumentId(DocumentId)
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    'Public Function GetDocumentByContainerId(ContainerId As String) As DocumentResult
    '    Try
    '        Return _channel.GetDocumentByContainerId(ContainerId)
    '    Catch ex As Exception
    '        _logger.Error(ex)
    '        Throw ex
    '    End Try
    'End Function

    ''' <summary>
    ''' Aborts the channel and creates a new connection
    ''' </summary>
    Private Sub Reconnect()
        _logger.Warn("Connection faulted. Trying to reconnect..")

        Try
            _channel.Abort()
            _channel = GetChannel()
            _channel.Open()
        Catch ex As Exception
            _logger.Error(ex)
        End Try
    End Sub

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

            AddHandler oChannel.Faulted, AddressOf Reconnect

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