using System;
using System.IO;

namespace Addison_Wesley.Codebook.Filesystem
{
   public class FolderUtils
   {
      /// <summary>
      /// Porovná dvě složky
      /// </summary>
      /// <param name="folder1">Odkaz na instanci typu DirectoryInfo pro první adresář</param>
      /// <param name="folder2">Odkaz na instanci typu DirectoryInfo pro druhý adresář</param>
      /// <param name="compareFileContent">Udává, zda má být porovnáván obsah 
      /// odpovídajících souborů v adresářích</param>
      /// <returns>Vrátí true, jsou-li oba adresáře totožné</returns>
      public static bool CompareFolder(DirectoryInfo folder1,
         DirectoryInfo folder2, bool compareFileContent)
      {
         // Porovnání počtu souborů v adresářích
         FileInfo[] files1 = folder1.GetFiles();
         FileInfo[] files2 = folder2.GetFiles();
         if (files1.Length != files2.Length)
         {
            return false;
         }

         // Projdeme soubory a porovnáme je
         foreach (FileInfo file1 in files1)
         {
            // Zjistíme jména souborů v druhém adresáři a otestujeme, 
            // zda existuje odpovídající soubor
            string fileName2 = Path.Combine(folder2.FullName, file1.Name);
            if (System.IO.File.Exists(fileName2))
            {
               // Soubory porovnáme
               FileUtils.FileCompareMethod compareMethod =
                  compareFileContent ? FileUtils.FileCompareMethod.Content :
                  FileUtils.FileCompareMethod.Date;

               if (FileUtils.CompareFiles(file1.FullName, fileName2,
                  compareMethod) == false)
               {
                  return false;
               }
            }
            else
            {
               // Soubor neexistuje, takže adresáře jsou různé
               return false;
            }
         }

         // Porovnáme počet podadresářů
         DirectoryInfo[] subFolders1 = folder1.GetDirectories();
         DirectoryInfo[] subFolders2 = folder2.GetDirectories();
         if (subFolders1.Length != subFolders2.Length)
         {
            return false;
         }

         // Projdeme podadresáře prvního adresáře a porovnáme, zda
         // druhý adrsář obsahuje tytéž podadresáře, a ty
         // pak rekurzivně projdeme
         foreach (DirectoryInfo subFolder1 in subFolders1)
         {
            // Zjistíme jméno druhého adresáře aotestujeme, 
            // zda existuje odpovídající adresář
            string folderPath2 = Path.Combine(folder2.FullName, subFolder1.Name);
            DirectoryInfo subFolder2 = new DirectoryInfo(folderPath2);
            if (subFolder2.Exists == false)
            {
               return false;
            }

            // Rekurzivní volán za ůčelem porovnání obou podadresářů
            if (CompareFolder(subFolder1, subFolder2,
               compareFileContent) == false)
            {
               return false;
            }
         }

         // Dojde-li metoda až sem, mají oba adresáře stejný obsah
         return true;
      }

      /// Porovná dvě složky
      /// </summary>
      /// <param name="folder1">Cesta k prvnímu adresáři</param>
      /// <param name="folder2">Cesta k druhému adresáři</param>
      /// <param name="compareFileContent">Udává, zda má být porovnáván obsah 
      /// odpovídajících souborů v adresářích</param>
      /// <returns>Vrátí true, jsou-li oba adresáře totožné</returns>
       public static bool CompareFolders(string folderPath1, string folderPath2,
         bool compareFileContent)
      {
         // Porovnání jmn předaných adresářů
         if (folderPath1.EndsWith("\\") == false) folderPath1 += "\\";
         if (folderPath2.EndsWith("\\") == false) folderPath2 += "\\";

         // Volání rekurzivní metodyse dvěma novými
         // instancemi typu  DirectoryInfo pro oba adresáře
         DirectoryInfo folder1 = new DirectoryInfo(folderPath1);
         DirectoryInfo folder2 = new DirectoryInfo(folderPath2);
         return FolderUtils.CompareFolder(folder1, folder2, compareFileContent);
      }
   }
}
