Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Interfaces
Imports DigitalData.Modules.Logging
Imports Microsoft.VisualBasic.FileIO

Namespace ZUGFeRD
    Public Class FileFunctions
        Private ReadOnly _logConfig As LogConfig
        Private ReadOnly _logger As Logger
        Private ReadOnly _mssql As MSSQLServer
        Private ReadOnly _filesystem As FilesystemEx

        Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
            _logConfig = LogConfig
            _logger = _logConfig.GetLogger()
            _mssql = MSSQL
            _filesystem = New FilesystemEx(LogConfig)
        End Sub

        Public Sub MoveFiles(
                         Args As WorkerArgs,
                         MessageId As String,
                         Files As List(Of FileInfo),
                         AttachmentFiles As List(Of FileInfo),
                         EmbeddedAttachments As List(Of PDFEmbeds.EmbeddedFile),
                         MoveDirectory As String,
                         IsSuccess As Boolean)

            Dim oFinalMoveDirectory As String = MoveDirectory
            Dim oDateSubDirectoryName As String = Now.ToString("yyyy\\MM\\dd")
            Dim oAttachmentDirectory As String = Path.Combine(oFinalMoveDirectory, Args.AttachmentsSubDirectory, oDateSubDirectoryName)

            ' Files will be moved to a subfolder for the current day if they are rejected
            If Not IsSuccess Then
                oFinalMoveDirectory = Path.Combine(oFinalMoveDirectory, oDateSubDirectoryName)
            End If

            ' Create directories if they don't exist
            If Not Directory.Exists(oFinalMoveDirectory) Then
                Try
                    Directory.CreateDirectory(oFinalMoveDirectory)
                Catch ex As Exception
                    _logger.Error(ex)
                End Try
            End If

            If Not Directory.Exists(oAttachmentDirectory) And AttachmentFiles.Count > 0 Then
                Try
                    Directory.CreateDirectory(oAttachmentDirectory)
                Catch ex As Exception
                    _logger.Error(ex)
                End Try
            End If

            ' Filter out Attachments from `Files`
            Dim oInvoiceFiles As List(Of FileInfo) = Files.Except(AttachmentFiles).ToList()

            ' Move PDF/A Files
            For Each oFile In oInvoiceFiles
                Try
                    Dim oFilePath = _filesystem.GetVersionedFilename(Path.Combine(oFinalMoveDirectory, oFile.Name))

                    _filesystem.MoveTo(oFile.FullName, oFilePath, oFinalMoveDirectory)

                    _logger.Info("File moved to {0}", oFilePath)
                Catch ex As Exception
                    _logger.Warn("Could not move file {0}", oFile.FullName)
                    _logger.Error(ex)
                End Try
            Next

            ' Move non-PDF/A Email Attachments/Files
            For Each oFile In AttachmentFiles
                Try
                    Dim oFilePath = _filesystem.GetVersionedFilename(Path.Combine(oAttachmentDirectory, oFile.Name))

                    _filesystem.MoveTo(oFile.FullName, oFilePath, oAttachmentDirectory)
                    _logger.Info("Attachment moved to {0}", oFilePath)
                Catch ex As Exception
                    _logger.Warn("Could not move attachment {0}", oFile.FullName)
                    _logger.Error(ex)
                End Try
            Next

            ' Write Embedded Files to disk
            For Each oResult In EmbeddedAttachments
                Try
                    Dim oFileName As String = $"{MessageId}~{oResult.FileName}"
                    Dim oFilePath As String = Path.Combine(oAttachmentDirectory, oFileName)

                    If Not File.Exists(oAttachmentDirectory) Then
                        Directory.CreateDirectory(oAttachmentDirectory)
                    End If

                    Using oWriter As New FileStream(oFilePath, FileMode.Create)
                        oWriter.Write(oResult.FileContents, 0, oResult.FileContents.Length)
                        _logger.Info("Embedded Attachment moved to {0}", oFilePath)
                    End Using
                Catch ex As Exception
                    _logger.Warn("Could not save embedded attachment {0}", oResult.FileName)
                    _logger.Error(ex)
                End Try
            Next

            _logger.Info("Finished moving files")
        End Sub
    End Class

End Namespace
