/*
         * Loop through the entire directory structure passed by sDir and generate an info.xml containing all the hashes.
         * Generating an update
         *  - Read files (recursively, go into the dirs) from the folder which will contain all the diffs, this is a separate folder
         *  - Compare against the old change set (if there is one, if not just add all the files and create the changeset_1.xml)
         *  - Create a list in the following format:
         * <ContentFile hash="13179176312914318240461532918490631599201219143227" filename="nightfiresource\base1.fgd" filesize="339355" mode="add" type="file" />
         *  - Generate the integrity file which will contain all the files and their hashes.
         *  - Keep track of deleted / created folders.
         */
        private void DirGenerateCaches(string origDir, int version)
        {
            var chSet           = ChangeSets.getChangeSetsClassPtr(origDir);
            var chSetFolderName = BuildCache.getMainCacheDirectory(chSet.getMainChangeSetDir());

            if (version > minimal_ver)
            {
                if (!chSet.LoadIntegrityfile(chSetFolderName))
                {
                    Console.WriteLine("No integrity file yet...");
                }
            }

            bool changeSetExists = chSet.DoesChangeSetExist(ChangeSets.CHANGESET_TYPES.CHANGESET_INTEGRITY_OLD);

            BuildCache.VerifyBootstrapper(chSetFolderName); //First and foremost check the bootstrapper version

            DiscordNotify.FormatDiscordPost($"\ud83d\udd27 Building a new {chSetFolderName} update!");
            DiscordNotify.SendDiscordPost(DiscordNotify.discordId, DiscordNotify.discordToken).Wait();

            try
            {
                IEnumerable <string> files = Directory.EnumerateFiles(origDir, "*.*", SearchOption.AllDirectories);
                foreach (string file in files)
                {
                    var    hashFuncs = new Hashing();
                    string SHA1Hash  = hashFuncs.genFileHash(file); //Generate our sha1 file hash which we'll use later on

                    string fileSize = new System.IO.FileInfo(file).Length.ToString();
                    //If the changeset list exists
                    if (changeSetExists)
                    {
                        //Huge perf hit, requires optimization... Although I can't see a better way to optimize this right now...
                        ChangeSets.MatchesResult flags = chSet.DoesFileHashMatch(ChangeSets.CHANGESET_TYPES.CHANGESET_INTEGRITY_OLD, file, SHA1Hash);
                        bool matches_hash     = (flags & ChangeSets.MatchesResult.matches_hash) != 0;
                        bool matches_filename = (flags & ChangeSets.MatchesResult.matches_filename) != 0;
                        //If there was a change from the previous changeset to now
                        if (!matches_hash)
                        {
                            //Add the change as an edit if it matches the filename in the hashes file, if not, it means we've added a file.
                            if (matches_filename)
                            {
                                chSet.AddToChangeSet(ChangeSets.CHANGESET_TYPES.CHANGESET_NEW, SHA1Hash, file, "file", fileSize, "edit");
                            }
                            else
                            {
                                chSet.AddToChangeSet(ChangeSets.CHANGESET_TYPES.CHANGESET_NEW, SHA1Hash, file, "file", fileSize, "add");
                            }
                        }
                    }
                    else
                    {
                        //If there's no changeset we're on the first revision
                        chSet.AddToChangeSet(ChangeSets.CHANGESET_TYPES.CHANGESET_NEW, SHA1Hash, file, "file", fileSize, "add");
                    }
                    chSet.AddToChangeSet(ChangeSets.CHANGESET_TYPES.CHANGESET_INTEGRITY_CURRENT, SHA1Hash, file, "file", fileSize, "add");
                }

                //Get the directory structure
                var directories = DirectorySearch.GetDirectories(origDir, "*", SearchOption.AllDirectories);
                foreach (string dir in directories)
                {
                    //Add every single directory to our current integrity file
                    chSet.AddToChangeSet(ChangeSets.CHANGESET_TYPES.CHANGESET_INTEGRITY_CURRENT, "", dir, "directory", "0", "add-dir");
                }

                //Check for newly added folders
                if (File.Exists(chSet.genSetName(chSetFolderName, "integrity.xml")))
                {
                    chSet.checkForNewlyAddedFolders(origDir);
                }

                //Check for any deleted files and folders by comparing the last integrity file to the actual directory structure (Adds to the new changeset list only)
                if (File.Exists(chSet.genSetName(chSetFolderName, "integrity.xml")))
                {
                    chSet.checkForDeletedFiles_Dirs(chSet.genSetName(chSetFolderName, "integrity.xml"));
                }

                //Create the directory (if it doesn't exist) where we'll have our changesets
                System.IO.Directory.CreateDirectory($"{chSetFolderName}-changesets");

                //Finally
                chSet.WriteChangeSetToXML(chSet.genSetName(chSetFolderName, $"changeset_{version}.xml"), ChangeSets.CHANGESET_TYPES.CHANGESET_NEW);
                chSet.WriteChangeSetToXML(chSet.genSetName(chSetFolderName, "integrity.xml"), ChangeSets.CHANGESET_TYPES.CHANGESET_INTEGRITY_CURRENT);

                /* Once everything's done, call BuildCache.Init to compress and copy the files over to the new directory.
                 *  Evaluate if we're copying from the new changeset or the entire integrity file, it should always be CHANGESET_NEW since full integrity is added on it at first but whatever...
                 */
                BuildCache.GenerateCacheFromChangeset(chSet, changeSetExists);

                //And last but not least, tell cloudflare to get rid of caches...
                CloudflarePurge cf = CloudflarePurge.getCloudflarePurgeClassPtr();
                if (cf.getAPIShouldPurgeCloudflare())
                {
                    cf.PurgeCache(cf.getAPIEmail(), cf.getAPIKey());
                }

                //Optionally, notify on discord
                TryReadAndSendDiscordUpdateChangelog(chSet, chSetFolderName, version);
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }