Module Job

    '//작업을 이어서하는 지 플래그
    Private Bw As System.Threading.Thread

    Structure RunParam
        Dim StartP As Integer
        Dim EndP As Integer
        Dim WorkDir As String
        Dim Replay As Boolean
        Dim isCopy As Boolean '//복사작업인가?
        Dim 원본폴더조합 As Boolean
        Dim 확장자 As String

        Public ReadOnly Property isFTPWork As Boolean
            Get
                If WorkDir.StartsWith("ftp:") Then
                    Return True
                Else
                    Return False
                End If
            End Get
        End Property
    End Structure

    Public Function Run(Param As RunParam) As Boolean

        PLog.Add("작업시작", True)

        '//일반 초기화
        PLog.Add("시스템초기화")
        Log = New ArrayList()
        log2 = New ArrayList()
        Backupfolder1.Clear()    '//기존의 백업폴더명을 삭제한다. (새로쓰기위해서)

        '//원본폴더조합기능이 켜져있는경우
        If Param.원본폴더조합 Then

            MDiMain.MSG("원본폴더조합시작")
            MDiMain.SubDirListCler() '//기존목록은 초기화한다.

            '//작업순서에 포함시킨다.
            Dim lv As ListViewItem = MDiMain.lvSchedule.Items.Add("폴더조합")
            lv.SubItems.Add("원본")
            lv.SubItems.Add("지정된 목록으로부터 하위폴더명을 추출합니다.")
            lv.SubItems.Add("대기")
            lv.SubItems.Add("-")
            MDiMain.lvSchedule.Refresh()

            MDiMain.Noti("하위폴더조합 실행")

            '//이어하기 작업이 설정되어있다면?
            Dim 체크섬 As String = ""
            If Not Prev_file Is Nothing Then
                체크섬 = FileCheckSum(Prev_file.FullName)
            End If
            Dim jobfile As String = String.Format("{0}\{1}_{2}_{3}_{4}_{5}.job", PathJob, Prev_file.Name, Prev_file.Length, Param.StartP, Param.EndP, 체크섬)
            Dim 폴더조합불러오기성공 As Boolean = False
            If Param.Replay Then
                '//원본폴더조합기능은 직접편집이아니고 불러온 파일명과 해당 파일의 크기가 동일한 기록이 있다면 그것을 이용한다
                If Not Prev_file Is Nothing AndAlso Prev_file.Exists Then
                    If System.IO.File.Exists(jobfile) Then
                        '//동일한 내역을 가진 job 파일이 있으므로 그것을 이용하도록 한다
                        Dim fi As New System.IO.FileInfo(jobfile)
                        If fi.Length > 0 Then
                            Try
                                Dim buffer As String = System.IO.File.ReadAllText(jobfile)
                                For Each line As String In buffer.Split(vbCrLf)
                                    If String.IsNullOrEmpty(line) Then Continue For
                                    MDiMain.AddSubDirList(line.Trim())
                                Next
                                폴더조합불러오기성공 = True

                                '//현재상태
                                lv.SubItems(2).Text = String.Format("{0}건 의 하위폴더가 설정됨", MDiMain.SubDirCount)
                                lv.SubItems(3).Text = "통과"
                                lv.BackColor = Color.LightSkyBlue
                                MDiMain.lvSchedule.Refresh()

                            Catch ex As Exception
                                PLog.Add("폴더조합불러오기오류 : " + ex.Message)
                            End Try
                        End If
                    End If
                End If
            End If

            If Not 폴더조합불러오기성공 Then
                '//새로 생성한다.

                '//프로그레스바 초기화
                MDiMain.ProgressSet(Param.EndP, Param.StartP, Param.StartP)

                '//수량 표시
                MDiMain.ShowCnt1(Param.StartP, Param.EndP)

                Dim rcnt As Integer = Param.EndP - Param.StartP + 1
                PLog.Add(String.Format("원본폴더 조합기능 시작({0})", rcnt))

                '//현재작업을 저장해준다
                Dim JobFileBuf As New System.Text.StringBuilder

                For i As Integer = Param.StartP To Param.EndP
                    MDiMain.ProgressVal(i)

                    '//작업진행사항을 표시해준다.
                    lv.SubItems(3).Text = String.Format("{0}/{1}", i, Param.EndP)
                    MDiMain.lvSchedule.Refresh()

                    Dim subdir As String = MDiMain.srcd_Get_FileList(i, "", Param.확장자).ToString
                    If subdir = "/" OrElse subdir = "\" OrElse subdir.ToLower().IndexOf("err") <> -1 Then Continue For
                    If Not MDiMain.CheckExistSubDir(subdir) Then
                        MDiMain.AddSubDirList(subdir) '//존재하는 항목은 추가되지 않는다.
                        JobFileBuf.AppendLine(subdir)
                    End If
                    Application.DoEvents()
                Next

                '//현재상태
                lv.SubItems(3).Text = "완료"
                lv.BackColor = Color.LightGreen
                MDiMain.lvSchedule.Refresh()

                '//완료목록을 저장해준다.
                System.IO.File.WriteAllText(jobfile, JobFileBuf.ToString())
            End If

        End If

        '//중간분리자
        MDiMain.AddScheduleDiv("파일목록 수집")

        '//파일정보수집
        MDiMain.MSG("파일정보수집")

        '//서브목록이있다면 그것들만 수집힌다.
        Dim fullsubdir As String
        Dim 재시도 As Boolean = False
retryFileSearch:

        '//폴더내의 파일목록을 수집한다.
        Dim 수집오류 As Boolean = False
        If MDiMain.HasSubDir Then  '//서브목록이 있다면

            '//프로그레스 설정과 현재 수량 표시
            MDiMain.ProgressSet(MDiMain.SubDirCount, 0, 0)

            For i As Integer = 1 To MDiMain.SubDirCount
                MDiMain.ShowCnt1(i, MDiMain.SubDirCount)
                MDiMain.ProgressVal(i)

                Dim lvSubDir As ListViewItem = MDiMain.list_subdir.Items(i - 1)
                fullsubdir = CStr(GetWorkDIr() & "\" & lvSubDir.Text).Replace("\\", "\")

                '//대상폴더가 FTP람녀 폴더구분기호를 \ 에서 / 로 변경해야한다.
                If Param.isFTPWork Then fullsubdir = fullsubdir.Replace("\", "/")

                Dim lvitem As ListViewItem = MDiMain.lvSchedule.Items.Add("검색")
                lvitem.SubItems.Add(fullsubdir)
                lvitem.SubItems.Add("파일목록을 작성합니다.")
                lvitem.SubItems.Add("대기")
                lvitem.SubItems.Add("-")
                MDiMain.lvSchedule.Refresh()
                Application.DoEvents()

                MDiMain.Noti("폴더검색" + vbCrLf + fullsubdir)

                If 재시도 AndAlso lvSubDir.ForeColor <> Color.Red Then
                    '//재시도이므로 처리하지 않는다
                    PLog.Add("재시도작업이므로 확인개체는 처리하지 않습니다(" + lvSubDir.Text + ")")
                    Continue For
                End If

                '//FTP가 대상일경우에는 별도 처리를 한다.
                If Param.isFTPWork Then
                    fullsubdir = fullsubdir.Replace("\", "/")
                    Dim ermsg As String = ""
                    Dim fnotfound As Boolean = False
                    Dim filecount As Integer = 0
                    Dim RetryCount As Integer = 0
RETRYFTP:
                    RetryCount += 1
                    If Not SearchFTP(Param, lvitem, fullsubdir, ermsg, fnotfound, filecount) Then
                        If Not fnotfound Then
                            '//오류가 발생했다면 3회정도 재시도를 한다.
                            If RetryCount <= MaxRetryCount Then
                                lvitem.ForeColor = Color.DarkMagenta
                                lvitem.SubItems(3).Text = String.Format("{0}/{1}", RetryCount, MaxRetryCount)
                                MDiMain.lvSchedule.Refresh()
                                PLog.Add(String.Format("재시도를 위해서 다음 시간을 기다림 : {0}ms", RetrySleeptime))
                                Threading.Thread.Sleep(RetrySleeptime)
                                Application.DoEvents()
                                GoTo RETRYFTP
                            Else
                                lvitem.ForeColor = Color.White
                                lvitem.BackColor = Color.DarkRed
                                lvitem.SubItems(3).Text = "오류"
                                MDiMain.lvSchedule.Refresh()
                                Application.DoEvents()
                            End If
                        End If
                    End If
                Else
                    SearchDir(Param, New DirectoryInfo(fullsubdir))
                    Application.DoEvents()
                End If

                '//delay
                Threading.Thread.Sleep(1000)
            Next
        Else   '//없으면 지정된 목록을 기준으로 잡는다
            'MsgBox("dirinfo" & New DirectoryInfo(GetWorkDIr).FullName)

            If Param.WorkDir.StartsWith("ftp:/") Then
                Dim ermsg As String = ""
                Dim fnotfound As Boolean = False
                Dim filecount As Integer = 0

                Dim lvitem As ListViewItem = MDiMain.lvSchedule.Items.Add("검색")
                lvitem.SubItems.Add(Param.WorkDir)
                lvitem.SubItems.Add("FTP 파일명수집")
                lvitem.SubItems.Add("대기")
                lvitem.SubItems.Add("-")

                MDiMain.Noti("폴더검색" + vbCrLf + Param.WorkDir)
                Application.DoEvents()

                If Not SearchFTP(Param, lvitem, GetWorkDIr, ermsg, fnotfound, filecount) Then
                    MsgBox("FTP경로조회가 실패되었습니다" + vbCrLf + ermsg, MsgBoxStyle.Critical, "확인")
                Else
                    Log.Add("FTP 파일조회성공 : " + Param.WorkDir + ":" + filecount.ToString())
                End If
            Else

                Dim lvitem As ListViewItem = MDiMain.lvSchedule.Items.Add("검색")
                lvitem.SubItems.Add(Param.WorkDir)
                lvitem.SubItems.Add("파일명수집")
                lvitem.SubItems.Add("대기")
                lvitem.SubItems.Add("-")
                MDiMain.lvSchedule.Refresh()
                Application.DoEvents()

                SearchDir(Param, New DirectoryInfo(Param.WorkDir))
            End If
        End If

        If 수집오류 Then
            If MsgBox("파일목록 수집오류가 발생하였습니다 " + vbCrLf + "다시시도 하시겠습니까?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "확인") = MsgBoxResult.Yes Then
                재시도 = True
                GoTo retryFileSearch
            Else
                MsgBox("현재목록을 가지고 진행합니다", MsgBoxStyle.Information, "확인")
            End If
        End If

        Addlog2("전체 그림파일 수  : " & MDiMain.DataSet1.FileList.Rows.Count & "개")
        PLog.Add(String.Format("Total Image Count : {0}", MDiMain.DataSet1.FileList.Rows.Count))

        If MDiMain.DataSet1.FileList.Rows.Count = 0 Then   '//목록이 하나도없다
            MsgBox("지정된 작업폴더내에 가능한 그림파일이 존재하지않습니다" & vbCrLf & "더이상 진행을 할 수 없습니다", MsgBoxStyle.Critical, "확인")
            Return False
        End If

        '//중간분리자
        MDiMain.AddScheduleDiv("원본목록 작성")
        Application.DoEvents()

        '//원본목록작성
        MDiMain.MSG("원본목록 작성")
        Dim SrcTxt As String
        Dim StartIndex As Integer = getSP()
        PLog.Add(String.Format("Make SourceList Range {0}~{1}", StartIndex, Ep))
        MDiMain.Noti("원본목록작성")
        For i As Integer = StartIndex To Ep
            MDiMain.ShowCnt1(i, Ep, "원본목록 작성중")
            SrcTxt = MDiMain.Get_SrcFileList(i + 1)
            If SrcTxt <> "" AndAlso SrcTxt <> "*" And SrcTxt <> "?" Then
                MDiMain.DataSet1.SrcList.Rows.Add(New String() {SrcTxt})
            End If
            Application.DoEvents()
        Next
        Addlog2("원본목록 수 : " & MDiMain.DataSet1.SrcList.Rows.Count & "개")
        PLog.Add(String.Format("Source List Count ={0}", MDiMain.DataSet1.SrcList.Count))


        '//중간분리자
        MDiMain.AddScheduleDiv("작업목록 작성")
        Application.DoEvents()

        '//이제 원본목록을 파일목로에서 검색한다. 데이터테이블의 Like 를 이요하면된다.
        '//그리고 검색된것들은 worklist 로보낸다.
        MDiMain.Noti("작업목록 작성")
        If GetrunType() = E_Runtype.Delete Then
            DeleteFileM(Param)
            Application.DoEvents()
        Else
            MoveFileM(Param)
            Application.DoEvents()
        End If

        Addlog2("작업목록 : " & MDiMain.DataSet1.WorkList.Rows.Count & "개")
        Return True

    End Function


    ''' <summary>
    ''' 지정된 FTP로부터 파일목록을 수신한다
    ''' </summary>
    ''' <param name="Di"></param>
    ''' <remarks></remarks>
    Public Function SearchFTP(ByRef Param As RunParam, ByRef lvitem As ListViewItem, ByVal Di As String, ByRef erMsg As String, ByRef NotFound As Boolean, ByRef filecnt As Integer) As Boolean
       
        Di = Di.Replace("ftp:/", "").Replace("//", "/")
        If Not Di.StartsWith("/") Then Di = "/" + Di
        If Di.EndsWith("/") Then Di = Di.Substring(0, Di.Length - 1)
        If Di.IndexOf("-원본") = -1 Then

            PLog.Add(String.Format("FTP 목록조회 : {0}", Di))

            '//FTP캐쉬폴더가 있다면 그것을 사용한다.(우선은 파일목록에대한 작업이다)
            Dim CacheDirName As String = PathJob + "\" + FTPServer + "\" + Di.Replace("/", "\") + "\summary.txt"
            CacheDirName = CacheDirName.Replace("\\", "\")

            '//수집된파일목록
            Dim filelist As New List(Of String)
            Dim SubDirList As New List(Of String)
            Dim 이어하기 As Boolean = False

            '//파일목록수집(기존정보의 사용이 허가된 경우 캐쉬파일에서 정보를 읽는다
            If Param.Replay AndAlso System.IO.File.Exists(CacheDirName) Then
                Dim SumFile As New ArinSetting.ArinSetting(CacheDirName)
                Dim 파일목록 As String = SumFile.Data("file", "list")
                For Each 파일 As String In 파일목록.Split(",")
                    If String.IsNullOrEmpty(파일) Then Continue For
                    If filelist.IndexOf(파일) = -1 Then filelist.Add(파일)
                Next
                Application.DoEvents()
                Dim 하위폴더목록 As String = SumFile.Data("subdir", "list")
                For Each 파일 As String In 하위폴더목록.Split(",")
                    If String.IsNullOrEmpty(파일) Then Continue For
                    If SubDirList.IndexOf(파일) = -1 Then SubDirList.Add(파일)
                Next
                If filelist.Count > 0 Then 이어하기 = True
                Application.DoEvents()
            End If

            '//파일목록이 불러와진게 없다면 FTP에서 조회를 시작한다.
            If filelist.Count < 1 Then

                Dim isErr As Boolean = False
                Dim ErrMsg As String = ""
                Dim dirlist As FTPClients.FTPdirectory
                Try
                    dirlist = FTP_0.ListDirectoryDetail(Di)
                Catch exw As System.Net.WebException

                    If TypeOf (exw.Response) Is System.Net.FtpWebResponse Then

                        PLog.Add("FTP목록조회오류(WEBEX) : " + exw.Message, True)
                        Dim ftpdesc As String = CType(exw.Response, System.Net.FtpWebResponse).StatusDescription
                        If ftpdesc.ToLower.IndexOf("directory not found") <> -1 Then
                            PLog.Add("폴더없음 오류코드이므로 정상 처리로 한다", True)
                            NotFound = True
                            erMsg = ftpdesc

                            lvitem.SubItems(2).Text = "폴더가 존재하지 않습니다"
                            lvitem.SubItems(3).Text = "완료"
                            lvitem.BackColor = Color.White '//성공했다
                            lvitem.ForeColor = Color.DimGray
                            Return False
                        Else
                            erMsg = exw.Message
                            lvitem.SubItems(2).Text = exw.Message
                            lvitem.SubItems(3).Text = "오류"
                            lvitem.BackColor = Color.Red
                            lvitem.ForeColor = Color.White
                            Return False
                        End If
                    Else
                        PLog.Add("FTP목록조회오류(WEBEX-2) : " + exw.Message, True)
                        erMsg = exw.Message
                        lvitem.SubItems(2).Text = exw.Message
                        lvitem.SubItems(3).Text = "오류"
                        lvitem.BackColor = Color.Red
                        lvitem.ForeColor = Color.White
                        Return False
                    End If

                Catch ex As Exception
                    PLog.Add("FTP목록조회오류(기타) : " + ex.Message, True)
                    erMsg = ex.Message
                    lvitem.SubItems(2).Text = ex.Message
                    lvitem.SubItems(3).Text = "오류"
                    lvitem.BackColor = Color.Red
                    lvitem.ForeColor = Color.White
                    Return False
                End Try

                Application.DoEvents()

                '//파일목록을 저장해서 캐쉬로사용하도록 한다.
                Dim sb_FileList As New System.Text.StringBuilder
                Dim fcnt1 As UInteger = 0
                For Each info As FTPClients.FTPfileInfo In dirlist.GetFiles(Param.확장자)
                    If info.FileType <> FTPClients.FTPfileInfo.DirectoryEntryTypes.File Then Continue For
                    fcnt1 += 1
                    sb_FileList.Append("," + info.Filename)
                    filelist.Add(info.Filename)
                    '//If filelist.Count Mod 50 = 0 Then
                    Application.DoEvents() '//160831
                    '//End If
                Next

                ''//ftp에러 오류없이 처리되었따
                'lvitem.ForeColor = Color.Black
                'lvitem.SubItems(2).Text = fcnt1.ToString()
                'lvitem.SubItems(3).Text = "완료"
                'If fcnt1 < 1 Then
                '    lvitem.BackColor = Color.WhiteSmoke '//성공했지만 파일은 없었다
                'Else
                '    lvitem.BackColor = Color.LightGreen '//성공했다
                'End If

                '//캐쉬파일을 생성해준다. 160716
                Dim fiCache As New System.IO.FileInfo(CacheDirName)
                If Not fiCache.Directory.Exists Then fiCache.Directory.Create()
                Dim summary As New ArinSetting.ArinSetting(fiCache.FullName)
                If Not summary.Exist Then summary.CreateFile()
                summary.Data("file", "count", "") = fcnt1.ToString()
                summary.Data("file", "list", "") = sb_FileList.ToString()

                Application.DoEvents()
                Dim foldlist2 As New System.Text.StringBuilder
                For Each info As FTPClients.FTPfileInfo In dirlist.GetDirectories
                    SubDirList.Add(info.NameOnly)
                    foldlist2.Append("," + info.NameOnly)
                Next

                '//하위목록도 저장해준다.
                summary.Data("subdir", "count", "") = SubDirList.Count.ToString()
                summary.Data("subdir", "list", "") = foldlist2.ToString()
                summary.Save()
                Application.DoEvents()
            End If

            '//수집된 파일목록을 데이터테이블에 기록한다.
            Dim fcnt As Integer = 0
            For Each File As String In filelist
                fcnt += 1
                MDiMain.MSG(MDiMain.DataSet1.FileList.Rows.Count & "개의 파일정보를 수집했습니다")
                MDiMain.DataSet1.FileList.Rows.Add(New String() {Di, File})
                Application.DoEvents()
            Next
            filecnt += fcnt
            lvitem.SubItems(2).Text = String.Format("{0}", fcnt)

            If 이어하기 Then
                lvitem.SubItems(3).Text = "통과"
                lvitem.BackColor = Color.LightSkyBlue
            Else
                lvitem.SubItems(3).Text = "완료"
                lvitem.BackColor = Color.LightGreen '//성공했다
            End If

            If fcnt = 0 Then
                lvitem.ForeColor = Color.Gray
            Else
                lvitem.ForeColor = Color.Black
            End If


            PLog.Add(String.Format("폴더검색결과({0}) 파일={1},폴더={2}", Di, filelist.Count, SubDirList.Count))
            MDiMain.MSG(MDiMain.DataSet1.FileList.Rows.Count & "개의 파일정보를 수집했습니다")
            Application.DoEvents()

            '//해당폴더의 서브폴더를 체크하도록 하였다면?
            If GetSubDir() Then

                '//여기서 폴더정보를 다시 수집한다.
                For Each DD As String In SubDirList
                    Dim subpath As String = Di + "/" + DD
                    subpath = subpath.Replace("//", "/")
                    subpath = subpath.Replace("\", "/")
                    PLog.Add(String.Format("Entering Subdir : {0}", subpath))

                    Dim fnotfound As Boolean
                    Dim filecount As Integer
                    Dim lvitemS As ListViewItem = MDiMain.lvSchedule.Items.Add("검색")
                    lvitemS.SubItems.Add(subpath)
                    lvitemS.SubItems.Add("FTP 파일명수집")
                    lvitemS.SubItems.Add("대기")
                    lvitemS.SubItems.Add("-")
                    MDiMain.lvSchedule.Refresh()
                    Application.DoEvents()

                    Dim RetryCount As Integer = 0
RETRYFTP:

                    If Not SearchFTP(Param, lvitemS, subpath, erMsg, fnotfound, filecount) Then
                        If Not fnotfound Then
                            '//오류가발생했지만 오류내용이 없다는 오류이다.(정상처리해야함)
                            If RetryCount <= MaxRetryCount Then
                                lvitem.ForeColor = Color.DarkMagenta
                                lvitem.SubItems(3).Text = String.Format("{0}/{1}", RetryCount, MaxRetryCount)
                                MDiMain.lvSchedule.Refresh()
                                PLog.Add(String.Format("재시도를 위해서 다음 시간을 기다림 : {0}ms", RetrySleeptime))
                                Threading.Thread.Sleep(RetrySleeptime)
                                Application.DoEvents()
                                GoTo RETRYFTP
                            Else
                                lvitem.ForeColor = Color.White
                                lvitem.BackColor = Color.DarkRed
                                lvitem.SubItems(3).Text = "오류"
                                MDiMain.lvSchedule.Refresh()
                                Application.DoEvents()
                            End If
                        End If
                    End If
                Next
            End If
        Else
            PLog.Add("SearchFTP Skip : " + Di)
        End If
        Return True
    End Function

    ''' <summary>
    ''' 해당디렉토리로부터 파일정보를 수집한다
    ''' </summary>
    ''' <param name="Di"></param>
    ''' <remarks></remarks>
    Public Function SearchDir(ByRef Param As RunParam, ByVal Di As DirectoryInfo) As Boolean
        If Di.Exists = False Then
            PLog.Add("폴더내파일검색 : 폴더없음 : " + Di.FullName, True)
            Return False
        End If

        If Di.FullName.IndexOf("-원본") = -1 Then

            PLog.Add("폴더내 파일검색 : " + Di.FullName)

            Try
                Dim FI() As FileInfo = Di.GetFiles("*." + Param.확장자)
                For Each F As FileInfo In FI
                    MDiMain.MSG(MDiMain.DataSet1.FileList.Rows.Count & "개의 파일정보를 수집했습니다")
                    MDiMain.DataSet1.FileList.Rows.Add(New String() {F.DirectoryName, F.Name})
                    Application.DoEvents()
                Next
                Application.DoEvents()
                If GetSubDir() Then
                    For Each DD As DirectoryInfo In Di.GetDirectories
                        SearchDir(Param, DD)
                    Next
                End If
                Return True
            Catch ex As Exception
                MsgBox("폴더정보를 불러오는데 실패했습니다" & vbCrLf & ex.Message.ToString, MsgBoxStyle.Information, "확인")
                Return False
            End Try
        Else
            PLog.Add("폴더내파일검색 : 원본폴더로인한 통과 : " + Di.FullName, True)
            Return False
        End If
    End Function


End Module
