using PkmnLib.Dynamic.ScriptHandling.Registry;

namespace PkmnLib.Dynamic.Plugins;

/// <summary>
/// A plugin is a way to register scripts and other components to the script registry.
/// </summary>
public interface IPlugin
{
    /// <summary>
    /// The configuration for the plugin. This is used to pass in any configuration options.
    /// </summary>
    IPluginConfiguration Configuration { get; }

    /// <summary>
    /// The name of the plugin. Mostly used for debugging purposes.
    /// </summary> 
    string Name { get; }

    /// <summary>
    /// When the plugin should be loaded. Lower values are loaded first.
    /// 0 should be reserved for the core battle scripts.
    /// </summary>
    uint LoadOrder { get; }

    /// <summary>
    /// Run the registration of the plugin when we're building the library.
    /// </summary>
    void Register(ScriptRegistry registry);
}

/// <inheritdoc cref="IPlugin"/>
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public abstract class Plugin<TConfiguration> : IPlugin where TConfiguration : IPluginConfiguration
{
    /// <inheritdoc />
    IPluginConfiguration IPlugin.Configuration => Configuration;

    /// <inheritdoc cref="IPlugin.Configuration"/>
    public TConfiguration Configuration { get; }

    /// <inheritdoc cref="Plugin{TConfiguration}"/>
    protected Plugin(TConfiguration configuration)
    {
        Configuration = configuration;
    }

    /// <summary>
    /// The name of the plugin. Mostly used for debugging purposes.
    /// </summary> 
    public abstract string Name { get; }

    /// <summary>
    /// When the plugin should be loaded. Lower values are loaded first.
    /// 0 should be reserved for the core battle scripts.
    /// </summary>
    public abstract uint LoadOrder { get; }

    /// <summary>
    /// Run the registration of the plugin when we're building the library.
    /// </summary>
    public abstract void Register(ScriptRegistry registry);
}

/// <summary>
/// Base class for plugin configuration.
/// </summary>
public interface IPluginConfiguration;