Imports Independentsoft.Email
Imports Independentsoft.Email.Pop3
Imports Independentsoft.Email.Smtp
Imports Independentsoft.Email.Mime
Imports Independentsoft.Email.Imap
Imports DigitalData.EMLProfiler.ClassCurrent
Imports DigitalData.Modules.Logging
Imports System.Net

Public Class clsEmail
    Private Shared Logger As DigitalData.Modules.Logging.Logger
    Public Shared EMAIL_INBOX_LIST As New ArrayList()
    Sub New(LogConf As LogConfig)
        Logger = LogConf.GetLogger
    End Sub
    Private Shared Sub OnWriteLog(ByVal sender As Object, ByVal e As WriteLogEventArgs)
        Logger.Info(e.Log)
    End Sub
    Public Function POP3_COLLECT() As Boolean
        Try
            Logger.Debug(String.Format("Working on POP3_COLLECT....."))
            Dim oClient As New Pop3Client(MAIL_SERVER, MAIL_PORT)

            oClient.ValidateRemoteCertificate = False
            oClient.Connect()
            Logger.Debug(String.Format("..connected!"))
            oClient.Login(MAIL_USER, MAIL_USER_PW)

            Dim oMessageInfo As MessageInfo() = oClient.List()
            Dim oCOUNT As Integer = 0
            For i As Integer = 0 To oMessageInfo.Length - 1

                Dim oMessage As Message = oClient.GetMessage(oMessageInfo(i).Index)
                Dim oMsgId_AlreadyExists As Boolean = False
                For Each pulled_msg As Message In CURRENT_WORKMAIL_LIST
                    If pulled_msg.MessageID = oMessage.MessageID Then
                        oMsgId_AlreadyExists = True
                    End If
                Next
                If oMsgId_AlreadyExists = False Then
                    oCOUNT += 1
                    CURRENT_WORKMAIL_LIST.Add(oMessage)
                    Logger.Debug(String.Format("Message [{0}] added to working Mail_List", oMessage.Subject))
                End If


                'client.Delete(messageInfo(i).Index)
            Next
            Logger.Debug($"{oCOUNT.ToString} messages will be worked..")
            oClient.Disconnect()
            Logger.Debug(String.Format("POP3_COLLECT finished!"))
            Return True
        Catch ex As Exception
            Logger.Error(ex)
            ' clsLogger.Add("Unexpected Error in POP3_COLLECT: " & ex.Message)
            EventLog.WriteEntry("DD EmailProfiler", "Unexpected Error in POP3_COLLECT: " & ex.Message(), EventLogEntryType.Error)
            Return False
        End Try
    End Function
    Public Function TEST_POP3_COLLECT(MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) As Boolean
        Try
            Logger.Debug(String.Format("Working on TEST_POP3_COLLECT..."))
            Dim oPop3Client As New Pop3Client(MYMAIL_SERVER, MYMAIL_PORT)
            Dim oLogPath = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "Log\logindependentSoft.txt")
            Logger.Debug($"IsoftLog: {oLogPath}...")
            Dim oindependentLogger As New Independentsoft.Email.Logger(oLogPath)
            ' oPop3Client.ValidateRemoteCertificate = False
            oPop3Client.Logger = oindependentLogger
            oPop3Client.Connect()
            Logger.Debug(String.Format("..connected!"))
            oPop3Client.Login(MYMAIL_USER, MYMAIL_USER_PW)

            Dim messageInfo As MessageInfo() = oPop3Client.List()

            For i As Integer = 0 To messageInfo.Length - 1
                Dim message As Message = oPop3Client.GetMessage(messageInfo(i).Index)
                MsgBox($"Message-subject: {message.Subject}, Message unique ID = {messageInfo(i).UniqueID} added", )
            Next

            oPop3Client.Disconnect()
            MsgBox(String.Format("TEST_POP3_COLLECT finished!"))
            Return True
        Catch ex As Exception
            Logger.Error(ex)

            Return False
        End Try
    End Function
    Public Function DELETE_EMAIL(msgid As String, Optional CheckDeletedRun As Boolean = False)
        Try
            If CURRENT_POLL_TYPE = "POP" Then
                Dim client As New Pop3Client(MAIL_SERVER, MAIL_PORT)
                client.ValidateRemoteCertificate = False
                client.Connect()
                client.Login(MAIL_USER, MAIL_USER_PW)

                Dim messageInfo As MessageInfo() = client.List()

                For i As Integer = 0 To messageInfo.Length - 1
                    Dim message As Message = client.GetMessage(messageInfo(i).Index)
                    If message.MessageID = msgid Then
                        client.Delete(messageInfo(i).Index)
                        Logger.Info(String.Format("Message [{0}] was deleted!", message.Subject))
                        Exit For
                    End If
                Next
                client.Disconnect()
                Return True
            ElseIf CURRENT_POLL_TYPE = "IMAP" Then
                If CheckDeletedRun = True Then
                    Try
                        Logger.Debug(String.Format("Working on S22 Delete..."))
                        Using oClient As New S22.Imap.ImapClient(MAIL_SERVER, MAIL_PORT, MAIL_USER, MAIL_USER_PW, S22.Imap.AuthMethod.Login, True)
                            Dim oMessageIds As IEnumerable(Of UInteger) = oClient.Search(S22.Imap.SearchCondition.Unseen, MAIL_INBOX_NAME)
                            For Each oMessageId As UInteger In oMessageIds
                                If oMessageId = msgid Then
                                    Logger.Debug($"Message shall be deleted...")
                                    oClient.DeleteMessage(oMessageId)
                                    Logger.Debug($"Message has been deleted!")
                                End If
                            Next
                            oClient.Expunge() 'delete messages marked as deleted

                        End Using
                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("Error while deleting s22Mail: " & ex.Message)
                        Return False
                    End Try
                Else
                    Try
                        Logger.Debug(String.Format("Working on IMAP Delete..."))
                        Dim oIMAPClient As New ImapClient(MAIL_SERVER, MAIL_PORT)
                        oIMAPClient.EnableSsl = True
                        oIMAPClient.ValidateRemoteCertificate = False
                        oIMAPClient.Connect()
                        Try
                            oIMAPClient.Login(MAIL_USER, MAIL_USER_PW, AuthenticationType.Login)
                        Catch ex As Exception
                            Logger.Error(ex)
                            Logger.Warn("Error while loginImap.now trying Ntlm-Auth: " & ex.Message)
                            Try
                                oIMAPClient.Login(MAIL_USER, MAIL_USER_PW, AuthenticationType.Ntlm)
                            Catch ex1 As Exception
                                Logger.Error(ex)
                                Return False
                            End Try
                        End Try
                        Logger.Debug("Logged in for delete...")
                        oIMAPClient.SelectFolder(MAIL_INBOX_NAME)
                        Dim oEnvelopes As Envelope() = oIMAPClient.ListMessages()

                        For i As Integer = 0 To oEnvelopes.Length - 1
                            If oEnvelopes(i).MessageID = msgid Then
                                oIMAPClient.Delete(oEnvelopes(i).UniqueID) 'mark as deleted
                            End If
                        Next
                        oIMAPClient.Expunge() 'delete messages marked as deleted
                        Dim oDeleted As Boolean = True
                        For i As Integer = 0 To oEnvelopes.Length - 1
                            If oEnvelopes(i).MessageID = msgid Then
                                Logger.Debug("Message is still existing. Deleting did not work!")
                                oDeleted = False
                            End If
                        Next
                        oIMAPClient.Disconnect()
                        If oDeleted = False Then
                            DELETE_EMAIL(msgid, True)
                        Else
                            Return True
                        End If


                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("Error in IMAP Delete: " & ex.Message)
                        Return False
                    End Try
                End If




            Else
                Return False
            End If
        Catch ex As Exception
            Logger.Error(ex)
            'clsLogger.Add("Unexpected Error in DELETE_EMAIL: " & ex.Message)
            Return False
        End Try
    End Function
    Public Function Email_Send_Independentsoft(ByVal mailSubject As String, ByVal mailBody As String, mailto As String,
                                                     mailfrom As String, mailsmtp As String, mailport As Integer, mailUser As String, mailPW As String,
                                                     AUTH_TYPE As String, Optional attment As String = "")
        Try
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
            Logger.Debug($"in Email_Send_Independentsoft..")
            Dim empfaenger As String()
            If mailto.Contains(";") Then
                empfaenger = mailto.Split(";")
            Else
                ReDim Preserve empfaenger(0)
                empfaenger(0) = mailto
            End If
            Dim _error As Boolean = False
            'Für jeden Empfänger eine Neue Mail erzeugen
            For Each _mailempfaenger As String In empfaenger
                Logger.Debug($"Working on email for {_mailempfaenger}..")
                Try
                    Dim message As New Message()
                    message.From = New Mailbox(mailfrom, mailfrom)
                    message.[To].Add(New Mailbox(_mailempfaenger))
                    message.Subject = mailSubject
                    Logger.Debug($"Message created..")
                    Dim textBodyPart As New BodyPart()
                    textBodyPart.ContentType = New ContentType("text", "html", "utf-8")
                    textBodyPart.ContentTransferEncoding = ContentTransferEncoding.QuotedPrintable
                    textBodyPart.Body = mailBody
                    message.BodyParts.Add(textBodyPart)
                    If attment <> String.Empty Then
                        If System.IO.File.Exists(attment) Then
                            Dim attachment1 As New Attachment(attment)
                            If attment.ToLower.EndsWith("pdf") Then
                                attachment1.ContentType = New ContentType("application", "pdf")
                            ElseIf attment.ToLower.EndsWith("jpg") Then
                                attachment1.ContentType = New ContentType("application", "jpg")
                            ElseIf attment.ToLower.EndsWith("docx") Then
                                attachment1.ContentType = New ContentType("application", "MS-word")
                            End If
                            message.BodyParts.Add(attachment1)
                        Else
                            Logger.Warn($"Attachment {attment.ToString} is not existing!")
                        End If
                    End If
                    Dim client As SmtpClient
                    Try
                        client = New SmtpClient(mailsmtp, mailport)
                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("clsEmail.Create Client: " & ex.Message)
                        _error = True
                        Continue For
                    End Try
                    Try
                        client.Connect()
                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("clsEmail.Client.Connect1: " & ex.Message)
                        Logger.Debug("Error in ClientConnect - but still trying to send")
                        _error = True
                        ' Continue For
                    End Try
                    Logger.Debug("Connected to Client!")
                    If AUTH_TYPE = "SSL" Then
                        client.EnableSsl = True
                        'client.ValidateRemoteCertificate = True
                        Logger.Debug("Authentification via SSL.")
                    ElseIf AUTH_TYPE = "TLS" Then
                        ' client.ValidateRemoteCertificate = False
                        client.StartTls()
                        client.EnableSsl = False
                        Logger.Debug("Authentification via TLS. SSL disabled")
                    Else
                        client.EnableSsl = False
                        Logger.Debug("Authentification NONE. SSL disabled")
                    End If
                    Try

                        client.Connect()
                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("clsEmail.Client.Connect: " & ex.Message)
                        _error = True
                        ' Continue For
                    End Try
                    Try
                        If mailsmtp.Contains("office365.com") Then
                            client.Login(mailUser, mailPW, AuthenticationType.None)
                        Else
                            client.Login(mailUser, mailPW)
                        End If

                        Logger.Debug("Logged in!")
                    Catch ex As Exception
                        Logger.Error(ex)

                        Try
                            If mailsmtp.Contains("office365.com") Then
                                client.Login(mailUser, mailPW, AuthenticationType.Login)
                            Else
                                client.Login(mailUser, mailPW, AuthenticationType.Anonymous)
                            End If

                        Catch ex1 As Exception
                            Logger.Error(ex)

                            Try
                                client.Login(mailUser, mailPW, AuthenticationType.Login)
                            Catch ex2 As Exception
                                Logger.Error(ex)
                                Logger.Warn("clsEmail.Client.Login: " & ex.Message)
                                _error = True
                                client.Disconnect()
                                Continue For
                            End Try
                        End Try
                    End Try
                    Try
                        client.Send(message)
                        Logger.Info("Message to " & _mailempfaenger & " has been send.")
                        _error = False
                    Catch ex As Exception
                        Logger.Error(ex)
                        Logger.Warn("clsEmail.Client.Send: " & ex.Message)
                        _error = True
                        client.Disconnect()
                        Continue For
                    End Try
                    client.Disconnect()

                Catch ex As Exception
                    Logger.Error(ex)
                    _error = True
                End Try
            Next

            If _error = True Then
                Return False
            Else
                Return True
            End If
        Catch ex As Exception
            Logger.Error(ex)
            Return False
        End Try
    End Function

End Class
