Collection of builder modules to run for an instance of SobekCM / builder
Inheritance: SobekCM.Core.Settings.Builder_Settings
        /// <summary> Constructor for a new instance of the Actionable_Builder_Source_Folder class </summary>
        /// <param name="ExistingBaseInstance"> An existing base instance used to populate this class with data </param>
        /// <param name="BuilderModulesConfig"> Builder module configuration to use to process this incoming folder structure </param>
        /// <remarks> This extends the core class <see cref="Builder_Source_Folder"/> and adds some methods to perform work </remarks>
        public Actionable_Builder_Source_Folder(Builder_Source_Folder ExistingBaseInstance, Builder_Modules BuilderModulesConfig )
        {
            Allow_Deletes = ExistingBaseInstance.Allow_Deletes;
            Allow_Folders_No_Metadata = ExistingBaseInstance.Allow_Folders_No_Metadata;
            Allow_Metadata_Updates = ExistingBaseInstance.Allow_Metadata_Updates;
            Archive_All_Files = ExistingBaseInstance.Archive_All_Files;
            Archive_TIFFs = ExistingBaseInstance.Archive_TIFFs;
            BibID_Roots_Restrictions = ExistingBaseInstance.BibID_Roots_Restrictions;
            Failures_Folder = ExistingBaseInstance.Failures_Folder;
            Folder_Name = ExistingBaseInstance.Folder_Name;
            Inbound_Folder = ExistingBaseInstance.Inbound_Folder;
            Perform_Checksum = ExistingBaseInstance.Perform_Checksum;
            Processing_Folder = ExistingBaseInstance.Processing_Folder;

            BuilderModules = new List<iFolderModule>();

            // Copy over the folder modules
            foreach (Builder_Module_Setting settings in ExistingBaseInstance.Builder_Module_Settings)
            {
                iFolderModule module = BuilderModulesConfig.Get_Folder_Module_By_Key(settings.Key);
                if (module != null)
                    BuilderModules.Add(module);
            }
        }
        /// <summary> Refresh the settings and item list from the database </summary>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        public bool Refresh_Settings_And_Item_List()
        {
            // Disable the cache
            CachedDataManager.Settings.Disabled = true;

            Engine_Database.Connection_String = dbInstance.Connection_String;
            SobekCM_Database.Connection_String = dbInstance.Connection_String;
            Library.Database.SobekCM_Database.Connection_String = dbInstance.Connection_String;

            // Reload all the other data
            Engine_ApplicationCache_Gateway.RefreshAll(dbInstance);

            // Also, pull the engine configuration
            // Try to read the OAI-PMH configuration file
            if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "\\config\\user\\sobekcm_microservices.config"))
            {
                SobekEngineClient.Read_Config_File(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "\\config\\user\\sobekcm_microservices.config", Engine_ApplicationCache_Gateway.Settings.Servers.System_Base_URL);
            }
            else if (File.Exists(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "\\config\\default\\sobekcm_microservices.config"))
            {
                SobekEngineClient.Read_Config_File(Engine_ApplicationCache_Gateway.Settings.Servers.Base_Directory + "\\config\\default\\sobekcm_microservices.config", Engine_ApplicationCache_Gateway.Settings.Servers.System_Base_URL);
            }

            if (settings == null)
            {
                Add_Error_To_Log("Unable to pull the newest settings from the database", String.Empty, String.Empty, -1);
                return false;
            }

            // Save the item table
            itemTable = Library.Database.SobekCM_Database.Get_Item_List(true, null).Tables[0];

            // get all the info
            settings = InstanceWide_Settings_Builder.Build_Settings(dbInstance);
            BuilderSettings = new Builder_Modules();
            DataSet builderSettingsTbl = Engine_Database.Get_Builder_Settings(false, null);
            if (builderSettingsTbl == null)
            {
                Add_Error_To_Log("Unable to pull the newest BUILDER settings from the database", String.Empty, String.Empty, -1);
                return false;
            }
            if (!Builder_Settings_Builder.Refresh(BuilderSettings, builderSettingsTbl, false))
            {
                Add_Error_To_Log("Error building the builder settings from the dataset", String.Empty, String.Empty, -1);
                return false;
            }
            List<string> errors = BuilderSettings.Builder_Modules_From_Settings();

            if (( errors != null ) && ( errors.Count > 0 ))
            {
                long logId = Add_Error_To_Log("Error(s) builder the modules from the settings", String.Empty, String.Empty, -1);
                foreach (string thisError in errors)
                {
                    Add_Error_To_Log(thisError, String.Empty, String.Empty, logId);
                }
                return false;
            }

            // Add the event listeners
            foreach (iPreProcessModule thisModule in BuilderSettings.PreProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iSubmissionPackageModule thisModule in BuilderSettings.DeleteItemModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iSubmissionPackageModule thisModule in BuilderSettings.ItemProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iPostProcessModule thisModule in BuilderSettings.PostProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iFolderModule thisModule in BuilderSettings.AllFolderModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }

            return true;
        }
        /// <summary> Refresh the settings and item list from the database </summary>
        /// <returns> TRUE if successful, otherwise FALSE </returns>
        public bool Refresh_Settings_And_Item_List()
        {
            // Create the tracer for this
            Custom_Tracer tracer = new Custom_Tracer();

            // Disable the cache
            CachedDataManager.Settings.Disabled = true;

            // Set all the database strings appropriately
            Engine_Database.Connection_String = instanceInfo.DatabaseConnection.Connection_String;
            SobekCM_Item_Database.Connection_String = instanceInfo.DatabaseConnection.Connection_String;
            Library.Database.SobekCM_Database.Connection_String = instanceInfo.DatabaseConnection.Connection_String;

            // Get the settings values directly from the database
            settings = InstanceWide_Settings_Builder.Build_Settings(instanceInfo.DatabaseConnection);
            if (settings == null)
            {
                Add_Error_To_Log("Unable to pull the newest settings from the database", String.Empty, String.Empty, -1);
                return false;
            }

            // If this was not refreshed yet, ensure [BASEURL] is replaced
            if (!refreshed)
            {
                // Determine the base url
                string baseUrl = String.IsNullOrWhiteSpace(settings.Servers.Base_URL) ? settings.Servers.Application_Server_URL : settings.Servers.Base_URL;
                List<MicroservicesClient_Endpoint> endpoints = instanceInfo.Microservices.Endpoints;
                foreach (MicroservicesClient_Endpoint thisEndpoint in endpoints)
                {
                    if (thisEndpoint.URL.IndexOf("[BASEURL]") > 0)
                        thisEndpoint.URL = thisEndpoint.URL.Replace("[BASEURL]", baseUrl).Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://");
                    else if (( thisEndpoint.URL.IndexOf("http:/") < 0 ) && ( thisEndpoint.URL.IndexOf("https:/") < 0 ))
                        thisEndpoint.URL = ( baseUrl + thisEndpoint.URL).Replace("//", "/").Replace("http:/", "http://").Replace("https:/", "https://");
                }
                refreshed = true;
            }

            // Set the microservice endpoints
            SobekEngineClient.Set_Endpoints(instanceInfo.Microservices);

            // Load the necessary configuration objects into the engine application cache gateway
            try
            {
                Engine_ApplicationCache_Gateway.Configuration.OAI_PMH = SobekEngineClient.Admin.Get_OAI_PMH_Configuration(tracer);
            }
            catch (Exception ee)
            {
                Add_Error_To_Log("Unable to pull the OAI-PMH settings from the engine", String.Empty, String.Empty, -1);
                Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                return false;
            }

            try
            {
                Engine_ApplicationCache_Gateway.Configuration.Metadata = SobekEngineClient.Admin.Get_Metadata_Configuration(tracer);
            }
            catch (Exception ee)
            {
                Add_Error_To_Log("Unable to pull the metadata settings from the engine", String.Empty, String.Empty, -1);
                Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                return false;
            }

            try
            {
                Engine_ApplicationCache_Gateway.Configuration.Extensions = SobekEngineClient.Admin.Get_Extensions_Configuration(tracer);
            }
            catch (Exception ee)
            {
                Add_Error_To_Log("Unable to pull the extension settings from the engine", String.Empty, String.Empty, -1);
                Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                return false;
            }

            // Check for any enabled extensions with assemblies
            ResourceObjectSettings.Clear_Assemblies();
            try
            {
                if ((Engine_ApplicationCache_Gateway.Configuration.Extensions.Extensions != null) && (Engine_ApplicationCache_Gateway.Configuration.Extensions.Extensions.Count > 0))
                {
                    // Step through each extension
                    foreach (ExtensionInfo extensionInfo in Engine_ApplicationCache_Gateway.Configuration.Extensions.Extensions)
                    {
                        // If not enabled, skip it
                        if (!extensionInfo.Enabled) continue;

                        // Look for assemblies
                        if ((extensionInfo.Assemblies != null) && (extensionInfo.Assemblies.Count > 0))
                        {
                            // Step through each assembly
                            foreach (ExtensionAssembly assembly in extensionInfo.Assemblies)
                            {
                                // Find the relative file name
                                if (assembly.FilePath.IndexOf("plugins", StringComparison.OrdinalIgnoreCase) > 0)
                                {
                                    // Determine the network way to get there
                                    string from_plugins = assembly.FilePath.Substring(assembly.FilePath.IndexOf("plugins", StringComparison.OrdinalIgnoreCase));
                                    string network_plugin_file = Path.Combine(settings.Servers.Application_Server_Network, from_plugins);

                                    // Get the plugin filename
                                    string plugin_filename = Path.GetFileName(assembly.FilePath);

                                    // Does this local plugin directory exist for this extension?
                                    string local_path = Path.Combine(pluginRootDirectory, instanceInfo.Name, extensionInfo.Code);
                                    if (!Directory.Exists(local_path))
                                    {
                                        try
                                        {
                                            Directory.CreateDirectory(local_path);
                                        }
                                        catch (Exception ee)
                                        {
                                            Add_Error_To_Log("Error creating the necessary plug-in subdirectory", String.Empty, String.Empty, -1);
                                            Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                                            return false;
                                        }
                                    }

                                    // Determine if the assembly is here
                                    string local_file = Path.Combine(local_path, plugin_filename);
                                    if (!File.Exists(local_file))
                                    {
                                        File.Copy(network_plugin_file, local_file);
                                    }
                                    else
                                    {
                                        // Do a date check
                                        DateTime webFileDate = File.GetLastWriteTime(network_plugin_file);
                                        DateTime localFileDate = File.GetLastWriteTime(local_file);

                                        if (webFileDate.CompareTo(localFileDate) > 0)
                                        {
                                            File.Copy(network_plugin_file, local_file, true);
                                        }
                                    }

                                    // Also, point the assembly to use the local file
                                    assembly.FilePath = local_file;
                                }
                            }
                        }
                    }

                    // Now, also set this all in the metadata portion
                    // Copy over all the extension information
                    foreach (ExtensionInfo thisExtension in Engine_ApplicationCache_Gateway.Configuration.Extensions.Extensions)
                    {
                        if ((thisExtension.Enabled) && (thisExtension.Assemblies != null))
                        {
                            foreach (ExtensionAssembly thisAssembly in thisExtension.Assemblies)
                            {
                                ResourceObjectSettings.Add_Assembly(thisAssembly.ID, thisAssembly.FilePath);
                            }
                        }
                    }
                }
            }
            catch (Exception ee)
            {
                Add_Error_To_Log("Unable to copy the extension files from the web", String.Empty, String.Empty, -1);
                Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                return false;
            }

            // Finalize the metadata config
            Engine_ApplicationCache_Gateway.Configuration.Metadata.Finalize_Metadata_Configuration();

            // Set the metadata preferences for writing
            ResourceObjectSettings.MetadataConfig = Engine_ApplicationCache_Gateway.Configuration.Metadata;

            // Also, load the builder configuration this way
            try
            {
                builderSettings = SobekEngineClient.Builder.Get_Builder_Settings(false, tracer);
            }
            catch (Exception ee)
            {
                Add_Error_To_Log("Unable to pull the builder settings from the engine", String.Empty, String.Empty, -1);
                Add_Error_To_Log(ee.Message, String.Empty, String.Empty, -1);
                return false;
            }

            // Build the modules
            builderModules = new Builder_Modules(builderSettings);
            List<string> errors = builderModules.Builder_Modules_From_Settings(instanceInfo.Name);

            if (( errors != null ) && ( errors.Count > 0 ))
            {
                long logId = Add_Error_To_Log("Error(s) builder the modules from the settings", String.Empty, String.Empty, -1);
                foreach (string thisError in errors)
                {
                    Add_Error_To_Log(thisError, String.Empty, String.Empty, logId);
                }
                return false;
            }

            // Add the event listeners
            foreach (iPreProcessModule thisModule in builderModules.PreProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iSubmissionPackageModule thisModule in builderModules.DeleteItemModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iSubmissionPackageModule thisModule in builderModules.ItemProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iPostProcessModule thisModule in builderModules.PostProcessModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }
            foreach (iFolderModule thisModule in builderModules.AllFolderModules)
            {
                thisModule.Error += module_Error;
                thisModule.Process += module_Process;
            }

            return true;
        }