' Copyright (C) 2025  P4pillon.org
'
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU Affero General Public License as
' published by the Free Software Foundation, either version 3 of the
' License, or (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU Affero General Public License for more details.
'
' You should have received a copy of the GNU Affero General Public License
' along with this program.  If not, see <https://www.gnu.org/licenses/>.
Imports System.Xml
Imports System.IO.File


Public Class Form1

    Public discret_mode As Boolean
    Private Config As XmlDocument
    Private compteur_fichiers_sauvegardés As Integer


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Config = New XmlDocument
        Config.Load(Application.StartupPath & "\officine_backup_Config.xml")
        affiche_REPERTORY()
        Dim arguments As String() = Environment.GetCommandLineArgs()
        If arguments.Contains("discret") Then
            Me.WindowState = FormWindowState.Minimized
            Backup()
            Me.Close()
        End If
    End Sub


    Private Sub affiche_REPERTORY()
        DataGridView1.Rows.Clear()
        Dim xnList As XmlNodeList = Config.SelectNodes("/CONFIG/REPERTORY")
        For Each xn As XmlNode In xnList
            DataGridView1.Rows.Add()
            DataGridView1.Item(Source_column.Index, DataGridView1.Rows.Count - 1).Value = xn("SOURCE").InnerText
            DataGridView1.Item(Destination_column.Index, DataGridView1.Rows.Count - 1).Value = xn("DESTINATION").InnerText
        Next
    End Sub

    Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel1.LinkClicked
        Dim Source As String = ""
        Dim Destination As String = ""
        FolderBrowserDialog1.Description = "Choix du répertoire à sauvegarder"
        FolderBrowserDialog1.ShowDialog()
        Source = FolderBrowserDialog1.SelectedPath
        If Source = "" Then Exit Sub
        FolderBrowserDialog1.Description = "Choix de la destination de la sauvegarde"
        FolderBrowserDialog1.ShowDialog()
        Destination = FolderBrowserDialog1.SelectedPath
        If Destination = "" Then Exit Sub
        Dim REPERTORY As XmlElement = Config.CreateElement("REPERTORY", Config.DocumentElement.NamespaceURI)
        Dim SOURCEXML As XmlElement = Config.CreateElement("SOURCE", Config.DocumentElement.NamespaceURI)
        SOURCEXML.InnerText = Source
        REPERTORY.AppendChild(SOURCEXML)
        Dim DESTINATIONXML As XmlElement = Config.CreateElement("DESTINATION", Config.DocumentElement.NamespaceURI)
        DESTINATIONXML.InnerText = Destination
        REPERTORY.AppendChild(DESTINATIONXML)

        Config.DocumentElement.AppendChild(REPERTORY)
        Config.Save(Application.StartupPath & "\officine_backup_Config.xml")
        affiche_REPERTORY()
    End Sub

    Private Function getAllFolders(ByVal directory As String) As String()
        'Create object
        Dim fi As New IO.DirectoryInfo(directory)
        'Array to store paths
        Dim path() As String = {}
        'Loop through subfolders
        For Each subfolder As IO.DirectoryInfo In fi.GetDirectories()
            'Add this folders name
            Array.Resize(path, path.Length + 1)
            path(path.Length - 1) = subfolder.FullName
            'Recall function with each subdirectory
            For Each s As String In getAllFolders(subfolder.FullName)
                Array.Resize(path, path.Length + 1)
                path(path.Length - 1) = s
            Next
        Next
        Return path
    End Function

    Private Sub Backup()
        If My.Computer.FileSystem.FileExists(Application.StartupPath & "\log.txt") Then
            My.Computer.FileSystem.DeleteFile(Application.StartupPath & "\log.txt")
        End If
        My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\log.txt", "________________________________________" & vbCrLf & "DEBUT SAUVEGARDE " & Now.ToShortDateString & " " & Now.ToShortTimeString & vbCrLf & vbCrLf, True)
        LinkLabel2.Text = "Préparation..."
        Application.DoEvents()
        compteur_fichiers_sauvegardés = 0
        Dim xnList As XmlNodeList = Config.SelectNodes("/CONFIG/REPERTORY")
        Dim nombre_total_fichiers = 0
        For Each REPERTORY As XmlNode In xnList
            Dim File = Dir(REPERTORY("SOURCE").InnerText & "\*.*")
            While File <> ""
                nombre_total_fichiers = nombre_total_fichiers + 1
                File = Dir()
            End While
            For Each folder As String In IO.Directory.GetDirectories(REPERTORY("SOURCE").InnerText, "*", System.IO.SearchOption.AllDirectories)
                File = Dir(folder & "\*.*")
                While File <> ""
                    nombre_total_fichiers = nombre_total_fichiers + 1
                    File = Dir()
                End While
            Next
        Next
        My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\log.txt", nombre_total_fichiers.ToString & " fichiers examinés" & vbCrLf, True)
        ProgressBar1.Minimum = 1
        ProgressBar1.Maximum = nombre_total_fichiers
        ProgressBar1.Value = 1
        ProgressBar1.Step = 1
        LinkLabel2.Text = "Sauvegarde en cours ..."
        Application.DoEvents()
        For Each REPERTORY As XmlNode In xnList
            My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\log.txt", vbCrLf & REPERTORY("SOURCE").InnerText & " " & Now.ToShortDateString & " " & Now.ToShortTimeString & vbCrLf, True)
            Backup_Files(REPERTORY("SOURCE").InnerText, REPERTORY("DESTINATION").InnerText)
            For Each folder As String In IO.Directory.GetDirectories(REPERTORY("SOURCE").InnerText, "*", System.IO.SearchOption.AllDirectories)

                Dim Rep_out As String = REPERTORY("DESTINATION").InnerText & Mid(folder, REPERTORY("SOURCE").InnerText.Length + 1)
                Backup_Files(folder, Rep_out)
            Next
        Next
        My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\log.txt", compteur_fichiers_sauvegardés.ToString & " fichier(s) sauvegardé(s)" & vbCrLf, True)
        LinkLabel2.Text = "Exécuter la sauvegarde des données"
        Label1.Text = compteur_fichiers_sauvegardés.ToString & " fichier(s) sauvegardé(s)"
    End Sub


    Private Sub Backup_Files(ByVal Rep_In As String, Rep_out As String)

        If My.Computer.FileSystem.DirectoryExists(Rep_out) = False Then My.Computer.FileSystem.CreateDirectory(Rep_out)

        'nettoyage fichiers supprimmés de la source
        Dim file_dest = Dir(Rep_out & "\*.*")
        While file_dest <> ""
            If My.Computer.FileSystem.FileExists(Rep_In & "\" & file_dest) = False Then
                My.Computer.FileSystem.DeleteFile(Rep_out & "\" & file_dest)
            End If
            file_dest = Dir()
        End While

        'copie des fichiers
        Dim file_src = Dir(Rep_In & "\*.*")
   
        While file_src <> ""
            Try
                Label1.Text = Rep_In & "\" & file_src
            ProgressBar1.PerformStep()
            Application.DoEvents()
            If My.Computer.FileSystem.FileExists(Rep_out & "\" & file_src) = False Then
                    My.Computer.FileSystem.CopyFile(Rep_In & "\" & file_src, Rep_out & "\" & file_src, True)
                compteur_fichiers_sauvegardés = compteur_fichiers_sauvegardés + 1
            Else
                    If Math.Abs(DateDiff(DateInterval.Minute, GetLastWriteTime(Rep_In & "\" & file_src), GetLastWriteTime(Rep_out & "\" & file_src))) > 1 Then
                        My.Computer.FileSystem.CopyFile(Rep_In & "\" & file_src, Rep_out & "\" & file_src, True)
                        compteur_fichiers_sauvegardés = compteur_fichiers_sauvegardés + 1
                    End If
                End If
            Catch ex As Exception
                My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\log.txt", vbCrLf & Rep_In & "\" & file_src & vbCrLf & ex.Message & vbCrLf, True)
            End Try
            file_src = Dir()
        End While

    End Sub

    


    Private Sub LinkLabel2_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkLabel2.LinkClicked
        Backup()
    End Sub

    Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
        If e.ColumnIndex = Suppr_column.Index Then
            For Each REPERTORY As XmlNode In Config.SelectNodes("/CONFIG/REPERTORY")
                If REPERTORY("DESTINATION").InnerText = DataGridView1.Item(Destination_column.Index, DataGridView1.CurrentRow.Index).Value _
                    And REPERTORY("SOURCE").InnerText = DataGridView1.Item(Source_column.Index, DataGridView1.CurrentRow.Index).Value Then
                    REPERTORY.ParentNode.RemoveChild(REPERTORY)
                    Config.Save(Application.StartupPath & "\officine_backup_Config.xml")
                    affiche_REPERTORY()
                    Exit Sub
                End If
            Next
        End If
    End Sub

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

    End Sub
End Class
