using System.Linq.Expressions;
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
namespace AIStudio.Tools.PluginSystem;
///
/// Represents metadata for a configuration object from a configuration plugin. These are
/// complex objects such as configured LLM providers, chat templates, etc.
///
public sealed record PluginConfigurationObject
{
private static readonly SettingsManager SETTINGS_MANAGER = Program.SERVICE_PROVIDER.GetRequiredService();
private static readonly ILogger LOG = Program.LOGGER_FACTORY.CreateLogger();
///
/// The id of the configuration plugin to which this configuration object belongs.
///
public required Guid ConfigPluginId { get; init; } = Guid.NewGuid();
///
/// The id of the configuration object, e.g., the id of a chat template.
///
public required Guid Id { get; init; } = Guid.NewGuid();
///
/// The type of the configuration object.
///
public required PluginConfigurationObjectType Type { get; init; } = PluginConfigurationObjectType.NONE;
///
/// Cleans up configuration objects of a specified type that are no longer associated with any available plugin.
///
/// The type of configuration object to clean up.
/// The type of configuration object to process.
/// A selection expression to retrieve the configuration objects from the main configuration.
/// A list of currently available plugins.
/// A list of all existing configuration objects.
/// Returns true if the configuration was altered during cleanup; otherwise, false.
public static bool CleanLeftOverConfigurationObjects(
PluginConfigurationObjectType configObjectType,
Expression>> configObjectSelection,
IList availablePlugins,
IList configObjectList) where TClass : IConfigurationObject
{
var configuredObjects = configObjectSelection.Compile()(SETTINGS_MANAGER.ConfigurationData);
var leftOverObjects = new List();
foreach (var configuredObject in configuredObjects)
{
if(!configuredObject.IsEnterpriseConfiguration)
continue;
var configObjectSourcePluginId = configuredObject.EnterpriseConfigurationPluginId;
if(configObjectSourcePluginId == Guid.Empty)
continue;
var templateSourcePlugin = availablePlugins.FirstOrDefault(plugin => plugin.Id == configObjectSourcePluginId);
if(templateSourcePlugin is null)
{
LOG.LogWarning($"The configured object '{configuredObject.Name}' (id={configuredObject.Id}) is based on a plugin that is not available anymore. Removing the chat template from the settings.");
leftOverObjects.Add(configuredObject);
}
if(!configObjectList.Any(configObject =>
configObject.Type == configObjectType &&
configObject.ConfigPluginId == configObjectSourcePluginId &&
configObject.Id.ToString() == configuredObject.Id))
{
LOG.LogWarning($"The configured object '{configuredObject.Name}' (id={configuredObject.Id}) is not present in the configuration plugin anymore. Removing the chat template from the settings.");
leftOverObjects.Add(configuredObject);
}
}
// Remove collected items after enumeration to avoid modifying the collection during iteration:
var wasConfigurationChanged = leftOverObjects.Count > 0;
foreach (var item in leftOverObjects.Distinct())
configuredObjects.Remove(item);
return wasConfigurationChanged;
}
}