using System;
using System.Collections.Generic;
using System.IO.Compression;
using NugetForUnity.Configuration;
using NugetForUnity.Helper;
using NugetForUnity.PluginAPI;
using NugetForUnity.PluginAPI.ExtensionPoints;
using NugetForUnity.PluginAPI.Models;
using UnityEditor;
using UnityEngine;
namespace NugetForUnity.PluginSupport
{
///
/// Plugin Registry loads the plugins and provides methods for calling them.
///
internal class PluginRegistry : INugetPluginRegistry,
IPackageButtonsHandler,
IPackageInstallFileHandler,
IPackageUninstallHandler,
IFoundInstalledPackageHandler
{
private readonly List foundInstalledPackageHandlers = new List();
private readonly List packageButtonsHandlers = new List();
private readonly List packageInstallFileHandlers = new List();
private readonly List packageUninstallHandlers = new List();
///
/// Gets the static instance of PluginRegistry.
///
public static PluginRegistry Instance { get; private set; }
///
/// Gets a value indicating whether we are running from Unity or from CLI version.
///
public bool IsRunningInUnity { get; } = SessionState.GetString(nameof(IsRunningInUnity), "true") == "true";
///
public INugetPluginService PluginService { get; } = new NugetPluginService();
///
/// Reloads appropriate plugins after some are enabled or disabled.
///
public static void Reinitialize()
{
if (Instance?.PluginService is IDisposable disposable)
{
disposable.Dispose();
}
Instance = null;
InitPlugins();
}
///
/// Loads the plug-ins that are enabled in preferences and initialized Instance.
///
public static void InitPlugins()
{
if (Instance != null)
{
return;
}
Instance = new PluginRegistry();
var loadedPlugins = new List();
var failedPlugins = new List();
foreach (var plugin in ConfigurationManager.NugetConfigFile.EnabledPlugins)
{
try
{
var assembly = AssemblyLoader.Load(plugin);
var pluginLoaded = false;
foreach (var type in assembly.GetTypes())
{
if (typeof(INugetPlugin).IsAssignableFrom(type))
{
var pluginInstance = (INugetPlugin)Activator.CreateInstance(type);
pluginInstance.Register(Instance);
loadedPlugins.Add(plugin.Name);
pluginLoaded = true;
break;
}
}
if (!pluginLoaded)
{
failedPlugins.Add($"{plugin.Name}: No class implementing INugetPlugin found");
}
}
catch (Exception e)
{
failedPlugins.Add($"{plugin.Name}: {e.GetType().Name} {e.Message}");
}
}
if (loadedPlugins.Count > 0)
{
Debug.Log($"Loaded plugins: {string.Join(", ", loadedPlugins)}");
}
if (failedPlugins.Count > 0)
{
Debug.LogError($"Failed to load plugins: {string.Join("\n", failedPlugins)}");
}
}
///
public void RegisterPackageButtonDrawer(IPackageButtonsHandler packageButtonsHandler)
{
packageButtonsHandlers.Add(packageButtonsHandler);
}
///
public void RegisterPackageInstallFileHandler(IPackageInstallFileHandler packageInstallFileHandler)
{
packageInstallFileHandlers.Add(packageInstallFileHandler);
}
///
public void RegisterPackageUninstallHandler(IPackageUninstallHandler packageUninstallHandler)
{
packageUninstallHandlers.Add(packageUninstallHandler);
}
///
public void RegisterFoundInstalledPackageHandler(IFoundInstalledPackageHandler foundInstalledPackageHandler)
{
foundInstalledPackageHandlers.Add(foundInstalledPackageHandler);
}
///
public void DrawButtons(INugetPackage package, INugetPackage installedPackage, bool existsInUnity)
{
foreach (var packageButtonsHandler in packageButtonsHandlers)
{
try
{
packageButtonsHandler.DrawButtons(package, installedPackage, existsInUnity);
}
catch (Exception e)
{
Debug.LogError($"Exception while executing DrawButtons plugin handler {e}");
}
}
}
///
public bool HandleFileExtraction(INugetPackage package, ZipArchiveEntry entry, string extractDirectory)
{
foreach (var packageInstallFileHandler in packageInstallFileHandlers)
{
try
{
if (packageInstallFileHandler.HandleFileExtraction(package, entry, extractDirectory))
{
return true;
}
}
catch (Exception e)
{
Debug.LogError($"Exception while executing file extraction plugin handler {e}");
}
}
return false;
}
///
public void HandleUninstall(INugetPackage package, PackageUninstallReason uninstallReason)
{
foreach (var uninstallHandler in packageUninstallHandlers)
{
try
{
uninstallHandler.HandleUninstall(package, uninstallReason);
}
catch (Exception e)
{
Debug.LogError($"Exception while executing Uninstall plugin handler {e}");
}
}
}
///
public void HandleUninstalledAll()
{
foreach (var uninstallHandler in packageUninstallHandlers)
{
try
{
uninstallHandler.HandleUninstalledAll();
}
catch (Exception e)
{
Debug.LogError($"Exception while executing UninstallAll plugin handler {e}");
}
}
}
///
public void ProcessInstalledPackage(INugetPackage installedPackage)
{
foreach (var foundInstalledPackageHandler in foundInstalledPackageHandlers)
{
try
{
foundInstalledPackageHandler.ProcessInstalledPackage(installedPackage);
}
catch (Exception e)
{
Debug.LogError($"Exception while executing ProcessInstalledPackage plugin handler {e}");
}
}
}
}
}