Imports WINDREAMLib
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports System.Text

Public Class clsDateiverarbeitung

#Region "***** Variablen und Konstanten*****"
    Public Shared _windream As New clsWindream_allgemein


    Public Shared pr_DTPROFIL_REGELN As DataTable
    Public Shared aktfile_Exportresult


    Public Shared CriticalError As Boolean = False

    Private Shared regel_TYP, regel_INDEX_NAME, regel_QUELLE1, regel_FROM1, regel_FROM2 As String
    Private Shared Indexe() As String = Nothing  ' zum Speichern der Indexe
    Private Shared NI_Values() As String = Nothing  ' zum Speichern der Werte

    Private Shared WD_aktivesDokument As WMObject


    Const WMObjectStreamOpenModeReadWrite = 2
    Const WMObjectEditModeFileSystem = &H15
#End Region
    Public Shared Function InitProfilData()
        Try
            pr_DTPROFIL_REGELN = Nothing
            ' Profildaten der Klasse mitteilen
            clsLogger.AddDetailLog("InitProfilData Profildaten zugewiesen....")
            Return True
        Catch ex As Exception
            clsLogger.AddError(ex.Message, "cls_DV.InitProfilData")
            Return False
        End Try
    End Function
    'Kopiert die übergebene Datei in den Zielpfad
    Public Shared Function Export_File(WDDatei As WMObject, Zielpfad As String)
        Try
            If Not Zielpfad.EndsWith("\") Then
                Zielpfad = Zielpfad & "\"
            End If
            clsLogger.Add("", False)
            clsLogger.Add(">> Verarbeitung von Datei: " & WDDatei.aName, False)
            'Die Quelle zusammensetzen
            clsLogger.AddDetailLog("PFAD: " & WDLAUFWERK & ":" & WDDatei.aPath & "\" & WDDatei.aName)
            'Dim Quelle As String = IO.Path.GetDirectoryName(WDLaufwerk & ":" & WDDatei.aPath & "\" & WDDatei.aName)

            Dim ExportFileIO = New WMOTOOLLib.WMFileIO ' CreateObject("WMOTOOLLib.WMFileIO") ' New WMOTOOLLib.WMFileIO 
            clsLogger.AddDetailLog("ExportFileIO erzeugt.....")
            ' Stream Interface bereitstellen
            WDDatei.LockFor(WMObjectEditModeFileSystem)
            Try
                If Not WDDatei.aLocked Then
                    WDDatei.lock()
                End If
            Catch ex As Exception
                clsLogger.AddError("Unvorhergesehener Fehler beim Lock-Vorgang: " & ex.Message, "clsDV.Export_File")
                Return False
            End Try

            Dim oWMStream = WDDatei.OpenStream("BinaryObject", WMObjectStreamOpenModeReadWrite)
            '### VERSIONIERUNG ###
            Dim version As Integer = 2
            'Dim Stammname As String = System.IO.Path.GetFileNameWithoutExtension(Quelle)
            Dim Filename = WDDatei.aName.Substring(0, WDDatei.aName.LastIndexOf("."))
            Dim Extension = WDDatei.aName.Substring(WDDatei.aName.LastIndexOf("."))
            Dim tempFilename As String = Zielpfad & Filename & Extension
            'Überprüfen ob File existiert
            Do While IO.File.Exists(tempFilename) = True
                tempFilename = Zielpfad & Filename & "_" & version & Extension
                version = version + 1
            Loop
            clsLogger.AddDetailLog("Zieldateiname: " & tempFilename)
            ' den Dateiinhalt der neuen Datei zuweisen
            ExportFileIO.aWMStream = oWMStream
            ExportFileIO.bstrOriginalFileName = tempFilename
            'Das eigentliche kopieren
            ExportFileIO.ExportOriginal(True)
            ' close the windream file stream
            oWMStream.Close()
            WDDatei.Save()
            WDDatei.unlock()
            EXPORTED_FILENAME = tempFilename
            clsLogger.Add(">> Datei erfolgreich nach '" & tempFilename & "' verschoben.", False, "clsDV Export_File")
            aktfile_Exportresult = tempFilename
            Return True
        Catch ex As Exception
            'bei einem Fehler einen Eintrag in der Logdatei machen
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "clsDV.Export_File")
            Return False
        End Try
    End Function
    Public Shared Function Rename_File(WMFile As WMObject, konvention As String)
        Try
            clsLogger.AddDetailLog("Konvention: '" & konvention & "'")

            'Regulären Ausdruck zum Auslesen der windream-Indexe definieren
            Dim preg As String = "\[%{1}[a-zA-Z0-9\!\$\&\/\(\)\=\?\,\.\-\;\:_öÖüÜäÄ\#\'\+\*\~\{\}\@\€\<\>\ ]+]{1}"
            ' einen Regulären Ausdruck laden
            Dim regulärerAusdruck As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex(preg)
            ' die Vorkommen im SQL-String auslesen
            Dim reg_elemente As System.Text.RegularExpressions.MatchCollection = regulärerAusdruck.Matches(konvention)
            Dim i As Integer = 0
            ' alle Vorkommen der windream-Indexe im SQL-String durchlaufen
            For Each reg_element As System.Text.RegularExpressions.Match In reg_elemente
                'die Zeichen [% und ] entfernen (liefert den wirklichen windream-Index)
                Dim reg_element_Ohne_SZ As String = reg_element.Value.Replace("[%", "")
                reg_element_Ohne_SZ = reg_element_Ohne_SZ.Replace("]", "")
                clsLogger.AddDetailLog("Indexwert aus Index '" & reg_element_Ohne_SZ & "' auslesen....")
                Dim wdIndexwert
                'den Wert des Indexes für das aktuelle Dokument auslesen
                wdIndexwert = WMFile.GetVariableValue(reg_element_Ohne_SZ)
                If wdIndexwert Is Nothing = False Then
                    If Not wdIndexwert.GetType.ToString.Contains("System.Object") Then
                        clsLogger.AddDetailLog("Namenkonvention (" & i & ") " & konvention)
                        wdIndexwert = wdIndexwert.ToString.TrimEnd
                        wdIndexwert = wdIndexwert.ToString.TrimStart
                        clsLogger.AddDetailLog("Ausgelesener Indexwert = '" & wdIndexwert & "'")
                        konvention = konvention.Replace(reg_element.Value, wdIndexwert.ToString)
                        i += 1
                    Else
                        clsLogger.Add(">> Achtung gelesener Wert ist ein Vektorfeld - keine Umbenennung möglich ", False, "clsProfil.Profil_Durchlauf")
                    End If
                End If
            Next
            Dim version As Integer = 2
            Dim ZielPfad As String = Path.GetDirectoryName(aktfile_Exportresult)
            clsLogger.AddDetailLog("ZielPfad: " & ZielPfad)
            Dim Filename = konvention
            Dim Extension = Path.GetExtension(aktfile_Exportresult)
            clsLogger.AddDetailLog("Extension: " & Extension)
            Dim tempFilename As String = ZielPfad & "\" & Filename & Extension
            clsLogger.AddDetailLog("tempFilename: " & tempFilename)
            'Überprüfen ob File existiert
            Do While IO.File.Exists(tempFilename) = True
                tempFilename = ZielPfad & "\" & Filename & "~" & version & Extension
                version += 1
            Loop
            clsLogger.AddDetailLog("RenameFile - OLDFilename: " & aktfile_Exportresult & " - NEWFilename: " & Path.GetFileName(tempFilename))
            My.Computer.FileSystem.RenameFile(aktfile_Exportresult, Path.GetFileName(tempFilename))
            clsLogger.Add(">> Datei wurde erfolgreich umbenannt.", False, "clsProfil.RenameFile")
            Return True
        Catch ex As Exception
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "clsProfil.RenameFile")
            Return False
        End Try
    End Function
    Public Shared Function Rename_File_Vektor(WMFile As WMObject, WMINDEX_NAME As String)
        Try
            Dim WMIndexwert
            Dim ZielPfad As String = Path.GetDirectoryName(aktfile_Exportresult)
            clsLogger.AddDetailLog("ZielPfad: " & ZielPfad)
            Dim Extension = Path.GetExtension(aktfile_Exportresult)
            clsLogger.AddDetailLog("Extension: " & Extension)

            If WMINDEX_NAME.StartsWith("[%") Then
                WMINDEX_NAME = WMINDEX_NAME.Replace("[%", "")
                WMINDEX_NAME = WMINDEX_NAME.Replace("]", "")
            End If
            'den Wert des Indexes für das aktuelle Dokument auslesen
            WMIndexwert = WMFile.GetVariableValue(WMINDEX_NAME)
            If WMIndexwert.GetType.ToString.Contains("System.Object") Then
                clsLogger.AddDetailLog("Rename_File_Vektor in Progress for index " & WMINDEX_NAME)
                Dim anz As Integer = 1
                Dim copybasefile As String
                For Each WMvalue As Object In WMIndexwert
                    'Für jeden Value eine Datei erzeugen
                    Try
                        If WMvalue.ToString <> String.Empty Then
                            Dim tempFilename As String = ZielPfad & "\" & WMvalue & Extension
                            clsLogger.AddDetailLog("tempFilename: " & tempFilename)
                            If anz = 1 Then
                                clsLogger.AddDetailLog("RenameFile - OLDFilename: " & aktfile_Exportresult & " - NEWFilename: " & Path.GetFileName(tempFilename))
                                My.Computer.FileSystem.RenameFile(aktfile_Exportresult, Path.GetFileName(tempFilename))
                                copybasefile = tempFilename
                            Else
                                Dim version As Integer = 2
                                'Überprüfen ob File existiert
                                Do While IO.File.Exists(tempFilename) = True
                                    tempFilename = ZielPfad & "\" & WMvalue & "~" & version & Extension
                                    version += 1
                                Loop
                                File.Copy(copybasefile, tempFilename, True)
                            End If
                            anz += 1

                        End If
                    Catch ex As Exception
                        clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "clsDateiverarbeitung.ForEachWMvalue")
                    End Try
                Next
            Else
                clsLogger.Add(">> Achtung WMIndex " & WMINDEX_NAME & " scheint kein Vektorfeld zu sein!", False, "clsDateiverarbeitung.Rename_File_Vektor")
                Return False
            End If

            clsLogger.Add(">> Dateien wurde erfolgreich nach Vektorfeld erzeugt.", False, "clsDateiverarbeitung.Rename_File_Vektor")
            Return True
        Catch ex As Exception
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "clsDateiverarbeitung.Rename_File_Vektor")
        End Try
    End Function

    Private Shared Function GetWMAPILink(docId As String, userId As String)
        Dim hostname = "http://documents.mylogitservices.syncreon.com:8100"
        Dim link As String = $"{hostname}/WMWebApi/windream.web.api/DigitalData/BNSDownload?docId={docId}&userId={userId}"

        Return link
    End Function

    Private Shared Function GetDocTypeCategory(docType As String)
        Select Case docType
            Case "Abliefernachweis"
                Return 5
            Case Else
                Return 0
        End Select
    End Function

    ''' <summary>
    ''' Generiert einen Link für BNS und fügt das Dokument WMFile 
    ''' ins BNS ein
    ''' </summary>
    ''' <param name="WMFile">Das WMObject, dass das aktuelle Dokument repräsentiert</param>
    ''' <param name="userId">Die eindeutige Benutzer Kennung für die Authentifizierung in Windream</param>
    Public Shared Function BNSjsonDownload(WMFile As WMObject, userId As String, apiAddress As String)
        Try
            ' Indizes für das aktuelle Dokument auslesen
            Dim SENDUNGNR = WMFile.GetVariableValue("Sendungnr")
            Dim DOKID = WMFile.GetVariableValue("Dokument-ID")
            Dim DOKART = WMFile.GetVariableValue("Dokumentart")
            Dim now As DateTime = DateTime.Now

            ' Download Link für Dokument erstellen
            Dim link As String = GetWMAPILink(DOKID, userId)

            ' JSON Payload erstellen und serialisieren
            Dim doc As New BNSDocument()
            doc.Bemerkung = DOKART
            'Dokumente sollen unbegrenzt gültig sein
            'doc.Ivalidfrom = now
            'doc.Ivaliduntil = now.AddDays(30)
            doc.Pfad = link
            doc.Dateiname = WMFile.aName
            doc.Kategorien = New List(Of BNSDocumentCategory) From {
                New BNSDocumentCategory With {.Id = GetDocTypeCategory(DOKART)}
            }

            Dim json As String = JsonConvert.SerializeObject(doc, Formatting.Indented)
            Dim bytes As Byte() = Encoding.Default.GetBytes(json)

            ' HTTP Request machen 
            ' Mandanten ID ist Standartmäßig 1
            Dim mandatenId As Integer = 1
            ' Für Tests auf Sendung gesetzt, später sollte dieser String konfigurierbar sein
            Dim geschaeftsObjekt = "Sendung"
            ' Für Tests wird hier die Sendungsnummer verwendet, später hängt der verwendete Index von 'geschaeftsObjekt' ab
            Dim geschaeftsId = SENDUNGNR
            Dim url As String = $"http://{apiAddress}/onwebui/api/Customer/{mandatenId}/{geschaeftsObjekt}/{geschaeftsId}/dokument"

            clsLogger.Add($">> Generiertes JSON: {json}", False, "BNSjsonDownload")
            clsLogger.Add($">> Creating WebRequest for {url}", False, "BNSjsonDownload")

            Dim req As HttpWebRequest = WebRequest.CreateHttp(url)

            req.Method = "POST"
            req.ContentType = "application/json"
            req.ContentLength = bytes.Length
            req.Timeout = 3000
            req.ServicePoint.Expect100Continue = False

            Dim reqStream As Stream = req.GetRequestStream()
            reqStream.Write(bytes, 0, bytes.Length)
            reqStream.Close()

            clsLogger.Add($">> Datei wird hochgeladen... docId: {DOKID}, dokart: {DOKART}, userId: {userId}", False, "BNSjsonDownload")
            clsLogger.Add($">> Upload URL: {url}", False, "BNSjsonDownload")

            Using res As HttpWebResponse = req.GetResponse()
                Dim code As HttpStatusCode = res.StatusCode
                Dim text As String = res.StatusDescription

                ' Status 201 Created bedeutet: Alles okay!
                If code = HttpStatusCode.Created Then
                    clsLogger.Add($">> Datei geschrieben! docId: {DOKID}, dokart: {DOKART}, userId: {userId}", False, "BNSjsonDownload")
                Else
                    Throw New Exception($"Server Error (HTTP {code}: {text})")
                End If
            End Using
            Return True
        Catch ex As Exception
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message & " - " & ex.Source, "BNSjsonDownload")
            Return True
        End Try
    End Function
    Public Shared Function RUN_ORACLE_COMMAND(WMFile As WMObject, OracleCS As String, OracleCommandRAW As String)
        Try
            Dim result = REGEX_REPLACE(WMFile, OracleCommandRAW)
            If result = Nothing Then
                Return False
            End If


            If clsDatatabase.ExecuteonOracleDb(OracleCS, result) = True Then
                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "RUN_ORACLE_COMMAND")
            Return False
        End Try
    End Function
    Public Shared Function RUN_MSSQL_COMMAND(WMFile As WMObject, MSSQLCS As String, SQLCommandRAW As String)
        Try
            Dim result = REGEX_REPLACE(WMFile, SQLCommandRAW)
            If result = Nothing Then
                Return False
            End If


            If clsDatatabase.ExecuteonMSSQL(MSSQLCS, result) = True Then
                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            clsLogger.AddError("Unvorhergesehener Fehler: " & ex.Message, "RUN_MSSQL_COMMAND")
            Return False
        End Try
    End Function

    Private Shared Function REGEX_REPLACE(WMFile As WMObject, _STRING As String)
        Try
            ' Regulären Ausdruck zum Auslesen der windream-Indexe definieren
            Dim preg As String = "\[%{1}[a-zA-Z0-9\!\$\&\/\(\)\=\?\,\.\-\;\:_öÖüÜäÄ\#\'\+\*\~\{\}\@\€\<\>\ ]+]{1}"
            ' einen Regulären Ausdruck laden
            Dim regulärerAusdruck As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex(preg)
            ' die Vorkommen im SQL-String auslesen
            Dim reg_elemente As System.Text.RegularExpressions.MatchCollection = regulärerAusdruck.Matches(_STRING)
            Dim i As Integer = 0
            ' alle Vorkommen der windream-Indexe im SQL-String durchlaufen
            For Each reg_element As System.Text.RegularExpressions.Match In reg_elemente
                ' die Zeichen [% und ] entfernen (liefert den wirklichen windream-Index)
                Dim reg_element_Ohne_SZ As String = reg_element.Value.Replace("[%", "")
                reg_element_Ohne_SZ = reg_element_Ohne_SZ.Replace("]", "")
                clsLogger.AddDetailLog("read indexvalue from index '" & reg_element_Ohne_SZ & "'....")
                If reg_element_Ohne_SZ = "EXPORTED_FILENAME" Then
                    If EXPORTED_FILENAME <> "" Then
                        _STRING = _STRING.Replace(reg_element.Value, EXPORTED_FILENAME)
                    End If
                Else
                    clsLogger.Add(">> Attention: WMIndex is an vectorfield - seperation of values via ;", False, "clsDateiverarbeitung.REGEX_REPLACE")
                    Dim wdIndexwert
                    ' den Wert des Indexes für das aktuelle Dokument auslesen
                    wdIndexwert = WMFile.GetVariableValue(reg_element_Ohne_SZ)
                    If wdIndexwert Is Nothing = False Then
                        If Not wdIndexwert.GetType.ToString.Contains("System.Object") Then

                            wdIndexwert = wdIndexwert.ToString.TrimEnd
                            wdIndexwert = wdIndexwert.ToString.TrimStart
                            clsLogger.AddDetailLog("Ausgelesener Indexwert = '" & wdIndexwert & "'")
                            _STRING = _STRING.Replace(reg_element.Value, wdIndexwert.ToString)
                            clsLogger.AddDetailLog("Namenkonvention  (" & i & ") " & _STRING)
                            i += 1
                        Else
                            Dim result As String = ""
                            For Each WMvalue As Object In wdIndexwert
                                If WMvalue.ToString <> String.Empty Then
                                    WMvalue = WMvalue.ToString.TrimEnd
                                    WMvalue = WMvalue.ToString.TrimStart
                                    If result = "" Then
                                        result = WMvalue
                                    Else
                                        result = result & ";" & WMvalue
                                    End If
                                End If
                            Next
                            _STRING = _STRING.Replace(reg_element.Value, wdIndexwert.ToString)


                            Return Nothing
                        End If
                    Else
                        clsLogger.Add(">> Attention: Indexvalue is NOTHING, standardvalue 0 will be used", False, "clsDateiverarbeitung.REGEX_REPLACE")
                        _STRING = _STRING.Replace(reg_element.Value, "0")
                    End If
                End If


            Next
            Return _STRING
        Catch ex As Exception
            clsLogger.AddError("Unexpected error: " & ex.Message, "REGEX_REPLACE")
            Return Nothing
        End Try
    End Function

    Public Class BNSDocument
        Public Doksourcetype As Integer = 3
        Public Pfad As String
        'Dokumente sollen unbegrenzt gültig sein
        'Public Ivalidfrom As DateTime
        'Public Ivaliduntil As DateTime
        Public Bemerkung As String
        Public Primaer As Boolean = False
        Public Fremsysid As Integer = 1
        Public Kategorien As List(Of BNSDocumentCategory)
        Public Dateiname As String
    End Class

    Public Class BNSDocumentCategory
        Public Id As Integer
    End Class

End Class

