using CringePlugins.Config;
using CringePlugins.Resolver;
using NuGet.Versioning;
using System.Collections.Immutable;
using System.Xml.Serialization;
namespace CringePlugins.Compatability;
[XmlType("PluginConfig")]
public class PluginLoaderConfig
{
///
/// Raw plugin and mod ids
///
[XmlArrayItem("Id")] public string[] Plugins { get; set; } = [];
///
/// Raw profiles
///
[XmlArrayItem("Profile")] public PluginLoaderProfile[] Profiles { get; set; } = [];
public PackagesConfig MigratePlugins(PackagesConfig old)
{
//ensure defaults are installed
var defaultConfig = PackagesConfig.Default;
var sources = old.Sources.ToBuilder();
foreach (var source in defaultConfig.Sources)
{
if (!sources.Contains(source))
sources.Add(source);
}
var pluginsBuilder = ImmutableArray.CreateBuilder();
var defaultVersion = new NuGetVersion(1, 0, 0);
foreach (var plugin in GetPlugins())
{
pluginsBuilder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}",
new(defaultVersion)));
}
foreach (var package in defaultConfig.Packages)
{
if (!pluginsBuilder.Any(x => x.Id == package.Id))
pluginsBuilder.Add(package);
}
var profiles = ImmutableArray.CreateBuilder();
foreach (var profile in Profiles)
{
var builder = ImmutableArray.CreateBuilder();
foreach (var plugin in profile.Plugins)
{
if (!IsValidPluginId(plugin))
continue;
builder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}",
new(defaultVersion)));
}
foreach (var package in defaultConfig.Packages)
{
if (!builder.Any(x => x.Id == package.Id))
builder.Add(package);
}
profiles.Add(new(profile.Name, builder.ToImmutable()));
}
return old with
{
Packages = pluginsBuilder.ToImmutable(),
Profiles = profiles.ToImmutable(),
Sources = sources.ToImmutable()
};
}
public HashSet GetPlugins() => GetPlugins(Plugins);
public HashSet GetMods() => GetMods(Plugins);
public Dictionary> GetPluginProfiles()
{
var dict = new Dictionary>(Profiles.Length);
foreach (var profile in Profiles)
{
dict[profile.Name] = GetPlugins(profile.Plugins);
}
return dict;
}
public Dictionary> GetModProfiles()
{
var dict = new Dictionary>(Profiles.Length);
foreach (var profile in Profiles)
{
dict[profile.Name] = GetMods(profile.Plugins);
}
return dict;
}
private static HashSet GetPlugins(string[] mixed)
{
var plugins = new HashSet();
foreach (var plugin in mixed)
{
if (!IsValidPluginId(plugin))
continue;
plugins.Add(plugin);
}
return plugins;
}
private static HashSet GetMods(string[] mixed)
{
var mods = new HashSet();
foreach (var plugin in mixed)
{
if (!ulong.TryParse(plugin, out var modId))
continue;
mods.Add(modId);
}
return mods;
}
private static bool IsValidPluginId(string pluginId)
{
var count = 0;
foreach (var c in pluginId)
{
if (c != '/')
continue;
count++;
if (count > 1)
return false;
}
return count == 1;
}
}