Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Linq
Imports System.Collections.Generic
Imports System.Data
Imports System.Threading
Imports System.Collections.Concurrent
Imports JF.PlmJobManager
Imports JF.PlmJobManager.JobServer
Imports JF.Tools
Imports JF
Imports Microsoft.VisualBasic.FileIO


'xReferences System.Data.DataSetExtensions.dll

'' Script to import objects and set status via csv file: 
''  Date         Person        ChangeInfo
''  04.03.2022   S.Gueth       created
''  16.01.2023   S.Gueth       updated / check if site id is active
''  
'' script that will import all objects from csv file and set the status of the objects that are defined in the csv file
'' - all csv files must be located in the folder #rootPath_DP#\#SiteID#
'' - sitid in JobManager must be activ
'' 
'' csv file content:
'' csv header:
'' addPLMProcessGroup;ProcState;CLIName
'' csv line:
'' #ProcStateCol#;#NewStatusValue#;#ObjectCLIName#
''
'' example csv file:
''
''addPLMProcessGroup;ProcState;CLIName
''ProcStateCol02;RUN.CBReleased;@DB/004204/01/fnd0consentdataset/ConsentStatement
''ProcStateCol05;RUN.Test;@DB/03213214-01/01/master/03213214-010101OD9
''ProcStateCol05;RUN.Test2;@DB@26-00000230@A@se part@26-00000230/A
''
''
'' csv line with addtional values (optional):
'' #ProcStateCol#;#NewStatusValue#;#ObjectCLIName#;#ObjectAttr01#;#ObjectAttrRf#
''
'' example csv file with addtional values (optional):
''
''addPLMProcessGroup;ProcState;CLIName;ObjectAttr01;ObjectAttr09
''ProcStateCol02;RUN.CBReleased;@DB/004204/01/fnd0consentdataset/ConsentStatement;test1;test2
''ProcStateCol05;RUN.Test;@DB/03213214-01/01/master/03213214-010101OD9;test1;test2
''ProcStateCol05;RUN.Test2;@DB@26-00000230@A@se part@26-00000230/A;test1;test2

'' #Doc: Parameter usage:
'' Parameter                                               Description   
'' /rootPath_DP=C:\JobServer\Root                          defines the root path    


Namespace JobMgrScript

    Public Class EditObjectProcStatusByCSVFile_cls

        Private InfoSysHeader As InfoSys.JF_InfoSys = Nothing
        Private InfoSysProtocol As InfoSys.JF_InfoSys = Nothing


        Public Function ScriptMain(ByVal JS_ScriptingInterface As JobServer.ScriptingInterface.Methodes) As JF_Return_cls


            ' Required class for returning script results
            Dim ScriptResult_r As New JF_Return_cls
            Dim PauseOnEnd As Boolean = False
            Dim ScriptParameter As String = JS_ScriptingInterface.ScriptDef.cmdPara

            InfoSysHeader = JS_ScriptingInterface.CurActiveInfoSysGet
            InfoSysProtocol = JS_ScriptingInterface.CurActiveInfoSysGet

            If System.Environment.MachineName.ToUpper Like ("ADDPLM-*") Then
                Stop
            End If

            'InfoSysProtocol.WaitForUIPrint = False
            'Call InfoSysProtocol.PrintTimerInit(500)
            'InfoSysProtocol.WaitForUIPrint = False
            'Call InfoSysProtocol.PrintTimerInit(500)

            Dim dataSourceObj As MyAppl_DataSource_cls = JS_ScriptingInterface.NewDataSourceObjGenerate("DataSource.EditObjectProcStatusByCSVFile")

            Try
                InfoSysProtocol.StatusBarProgressBarStart()
                PauseOnEnd = If(JS_ScriptingInterface.ParameterValueGet("PauseOnEnd") = "true", True, False)
                ScriptResult_r.ResetToDefaultValues()

                Dim rootPath_DP As String = JS_ScriptingInterface.ParameterValueGet("rootPath_DP")

                Dim rootPath_obj As New DirectoryInfo(rootPath_DP)

                ' cycle throug all directories in the rootPath
                For Each direcotry As DirectoryInfo In rootPath_obj.GetDirectories("*", IO.SearchOption.TopDirectoryOnly)

                    Dim siteIdCurrent As String = direcotry.Name

                    InfoSysProtocol.Print("")
                    InfoSysProtocol.PrintObject("Start processing site", siteIdCurrent)

                    ' import objects into jobmanager
                    ' get sitedef object
                    Dim SiteDef_Obj As SiteDef_cls = dataSourceObj.Sites_tbl_SiteDefGet_by_SiteId(siteIdCurrent)
                    If Not SiteDef_Obj.SiteDefFound_bol Then
                        InfoSysProtocol.PrintInfoLine("No SiteDef found for Site [" + siteIdCurrent + "] !!!")
                        Continue For
                    End If

                    ' check if site id is active
                    If Not SiteDef_Obj.SiteAktive_bol Then
                        InfoSysProtocol.PrintInfoLine("Site ID [" + siteIdCurrent + "] is not active -> Site ID will be skipped!!!")
                        Continue For
                    End If

                    ' get all csv files
                    For Each csv_obj As FileInfo In direcotry.GetFiles("*.csv", IO.SearchOption.TopDirectoryOnly)

                        Try

                            InfoSysProtocol.PrintObject("csv file", csv_obj.FullName)

                            ' read csv file
                            Dim JobMgrImportCsvFile_obj As JobMgrImportCsvFile_cls = New JobMgrImportCsvFile_cls(csv_obj.FullName, InfoSysProtocol)

                            ' execute Import
                            'Dim importTask As Threading.Tasks.Task = JS_ScriptingInterface.ObjectsList_Import_IR_DatasetsByList(SiteDef_Obj, JobMgrImportCsvFile_obj.IRListGet(), True, InfoSysProtocol)
                            'importTask.Wait()
                            Dim task = Threading.Tasks.Task.Run(Function() JS_ScriptingInterface.ObjectsList_Import_IR_DatasetsByList(SiteDef_Obj, JobMgrImportCsvFile_obj.IRListGet(), True, InfoSysProtocol))
                            task.Wait()

                            ' update status of objects in Jobmanager db
                            For Each JobMgrCsvLine_obj As JobMgrCsvLine_cls In JobMgrImportCsvFile_obj.JobMgrCsvLines

                                For Each DSEditObject As DSEdit_cls In JobMgrCsvLine_obj.DSEditObjectsGet(SiteDef_Obj.SiteID)

                                    Dim returnObj As JF_Return_cls = dataSourceObj.Objects_tbl_UpdateProcessState(DSEditObject)
                                    If returnObj.ResultIsEverythingOk Then
                                        InfoSysProtocol.Print(returnObj.ResultMsg)
                                    Else
                                        If returnObj.ExUp Then
                                            InfoSysProtocol.PrintEx(returnObj.Ex, "EX on updating obj [" + JobMgrCsvLine_obj.cliName + "] in JobMgrDB [" + DSEditObject.ColumeNameEditTarget + "|" + DSEditObject.EditValue.ValueNew + "]")
                                        Else
                                            InfoSysProtocol.Print("ERR on updating obj [" + JobMgrCsvLine_obj.cliName + "] in JobMgrDB [" + DSEditObject.ColumeNameEditTarget + "|" + DSEditObject.EditValue.ValueNew + "]")
                                        End If
                                    End If

                                Next

                            Next

                        Catch ex As Exception
                            Try
                                InfoSysProtocol.PrintEx(ex, "EX for csv file [" + csv_obj.FullName + "]")
                            Catch ex2 As Exception
                            End Try
                        End Try

                        ' copy file to processed folder
                        Dim processedFolder_DP As String = IO.Path.Combine(direcotry.FullName, "zzProcessed")
                        If Not IO.Directory.Exists(processedFolder_DP) Then
                            Try
                                IO.Directory.CreateDirectory(processedFolder_DP)
                            Catch ex As Exception
                                InfoSysProtocol.PrintEx(ex, "ERR on creating dir " + processedFolder_DP)
                            End Try
                        End If
                        Dim processedFile_DPNE As String = IO.Path.Combine(processedFolder_DP, JF.Tools.ParsePath_N(csv_obj.FullName) + "_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + JF.Tools.ParsePath_E(csv_obj.FullName))
                        Try
                            IO.File.Move(csv_obj.FullName, processedFile_DPNE)
                        Catch ex As Exception
                            InfoSysProtocol.PrintEx(ex, "ERR on moving file from " + csv_obj.FullName + " to " + processedFile_DPNE)
                        End Try

                    Next

                    InfoSysProtocol.PrintObject("End processing site", siteIdCurrent)

                Next


            Catch ex As Exception
                ScriptResult_r.Ex = ex
                ScriptResult_r.ExMsg = "Exeption in script:" + JS_ScriptingInterface.ScriptDef.NameDescription
                InfoSysProtocol.PrintEx(ex, "JobServerLogFileCleanUp.ScriptMain")
            End Try

            Return ScriptResult_r
        End Function

    End Class

    ''' <remarks> 
    ''' #New: 3.1601;07.03.2022;S.Gueth
    ''' </remarks>
    Class JobMgrImportCsvFile_cls

        Sub New(csvFile_DPNE_p As String, ByRef InfoSysProtocol_p As InfoSys.JF_InfoSys)
            Try
                Dim index As Integer = 0
                ' cycle through each csv line
                For Each line As String In IO.File.ReadLines(csvFile_DPNE_p)

                    If String.IsNullOrEmpty(line.Trim) Then
                        Continue For
                    End If

                    ' process the header for additional values
                    If index = 0 Then
                        Try
                            Dim lineIndex As Integer = 0
                            For Each header As String In line.Split(";".ToArray)
                                If lineIndex > 2 Then
                                    AdditionalColumns.Add(lineIndex, header.Trim(""""c))
                                End If
                                lineIndex += 1
                            Next
                        Catch ex As Exception
                        End Try
                    End If

                    ' do not process first line, because it is the header
                    If index > 0 Then
                        Try
                            JobMgrCsvLines.Add(New JobMgrCsvLine_cls(line, AdditionalColumns))
                        Catch ex As Exception
                            InfoSysProtocol_p.PrintEx(ex, "Ex on parsing line '" + line + "'")
                        End Try
                    End If
                    index += 1

                Next
            Catch ex As Exception
                InfoSysProtocol_p.PrintEx(ex, "Ex on reading file '" + csvFile_DPNE_p + "'")
            End Try
        End Sub

        Public Property JobMgrCsvLines As New List(Of JobMgrCsvLine_cls)
        Public Property AdditionalColumns As New Dictionary(Of Integer, String)

        ''' <summary>
        ''' function to get all item revisions as list
        ''' </summary>
        ''' <remarks> 
        ''' #New: 3.1601;07.03.2022;S.Gueth
        ''' </remarks>
        Public Function IRListGet() As List(Of String)

            Return (From obj As JobMgrCsvLine_cls In Me.JobMgrCsvLines Select obj.cliName_obj.ItemRev).ToList

        End Function

    End Class

    ''' <remarks> 
    ''' #New: 3.1601;07.03.2022;S.Gueth
    ''' </remarks>
    Class JobMgrCsvLine_cls

        Sub New(csvLine_p As String, additionalColumns_p As Dictionary(Of Integer, String))



            Dim csvLine As String = csvLine_p
            Using parser As New TextFieldParser(New StringReader(csvLine))
                parser.TextFieldType = FieldType.Delimited
                parser.SetDelimiters(";")
                parser.HasFieldsEnclosedInQuotes = True

                While Not parser.EndOfData
                    Dim fields = parser.ReadFields()
                    Me.procstateCol = fields(0)
                    Me.status = fields(1)
                    Me.cliName = fields(2)

                    For Each additionalColumn As KeyValuePair(Of Integer, String) In additionalColumns_p
                        Try
                            Dim index As Integer = additionalColumn.Key
                            Dim header As String = additionalColumn.Value
                            Dim value As String = fields(index)
                            additionalValuesToUpdate.Add(New Tuple(Of String, String)(header, value))
                        Catch ex As Exception
                        End Try
                    Next

                End While
            End Using



        End Sub

        Public Property procstateCol As String = ""
        Public Property status As String = ""
        Public Property cliName As String = ""
        Public ReadOnly Property cliName_obj As ObjectCliName_cls
            Get
                Static ObjectCliName_obj As ObjectCliName_cls = JobServer.ObjectCliName_cls.Parse(Me.cliName)
                Return ObjectCliName_obj
            End Get
        End Property
        Public Property additionalValuesToUpdate As New List(Of Tuple(Of String, String))

        ''' <summary>
        ''' return the ds edit object of csv line
        ''' </summary>
        ''' <remarks> 
        ''' #New: 3.1601;07.03.2022;S.Gueth
        ''' </remarks>
        Public Function DSEditObjectsGet(ByVal SiteID_p As String) As List(Of DSEdit_cls)

            Dim DSEdit_objects As New List(Of DSEdit_cls)

            Dim DSEdit_obj As DSEdit_cls

            ' get additional values first
            For Each additionalValue As Tuple(Of String, String) In Me.additionalValuesToUpdate

                Dim column As String = additionalValue.Item1
                Dim value As String = additionalValue.Item2

                DSEdit_obj = New DSEdit_cls
                DSEdit_obj.ColumeNameEditTarget_SetBy_ColumeName = column
                DSEdit_obj.EditValue.ValueNew = value
                DSEdit_obj.DS.DatasetCliName = Me.cliName
                DSEdit_obj.DS.Ir.ObjectFromSiteID = SiteID_p
                DSEdit_obj.DS.Ir.ItemName = Me.cliName_obj.Item
                DSEdit_obj.DS.Ir.Rev = Me.cliName_obj.Rev

                DSEdit_objects.Add(DSEdit_obj)
            Next

            ' get procstate col to update at the end
            DSEdit_obj = New DSEdit_cls()
            DSEdit_obj.ColumeNameEditTarget_SetBy_ColumeName = Me.procstateCol
            DSEdit_obj.EditValue.ValueNew = Me.status
            DSEdit_obj.DS.DatasetCliName = Me.cliName
            DSEdit_obj.DS.Ir.ObjectFromSiteID = SiteID_p
            DSEdit_obj.DS.Ir.ItemName = Me.cliName_obj.Item
            DSEdit_obj.DS.Ir.Rev = Me.cliName_obj.Rev

            DSEdit_objects.Add(DSEdit_obj)

            Return DSEdit_objects
        End Function

    End Class

End Namespace




