using System;
using System.Collections.Generic;
using System.IO;

namespace StellaOps.Plugin.Hosting;

public sealed class PluginHostOptions
{
    private readonly List<string> additionalPrefixes = new();
    private readonly List<string> pluginOrder = new();
    private readonly List<string> searchPatterns = new();

    /// <summary>
    /// Optional base directory used for resolving relative plugin paths. Defaults to <see cref="AppContext.BaseDirectory" />.
    /// </summary>
    public string? BaseDirectory { get; set; }

    /// <summary>
    /// Directory that contains plugin assemblies. Relative values are resolved against <see cref="BaseDirectory" />.
    /// Defaults to <c>PluginBinaries</c> under the base directory.
    /// </summary>
    public string? PluginsDirectory { get; set; }

    /// <summary>
    /// Primary prefix used to discover plugin assemblies. If not supplied, the entry assembly name is used.
    /// </summary>
    public string? PrimaryPrefix { get; set; }

    /// <summary>
    /// Additional prefixes that should be considered when building search patterns.
    /// </summary>
    public IList<string> AdditionalPrefixes => additionalPrefixes;

    /// <summary>
    /// Explicit plugin ordering expressed as assembly names without extension.
    /// Entries that are not discovered will be reported in <see cref="PluginHostResult.MissingOrderedPlugins" />.
    /// </summary>
    public IList<string> PluginOrder => pluginOrder;

    /// <summary>
    /// Optional explicit search patterns. When empty, they are derived from prefix settings.
    /// </summary>
    public IList<string> SearchPatterns => searchPatterns;

    /// <summary>
    /// When true (default) the plugin directory will be created if it does not exist.
    /// </summary>
    public bool EnsureDirectoryExists { get; set; } = true;

    /// <summary>
    /// Controls whether sub-directories should be scanned. Defaults to true.
    /// </summary>
    public bool RecursiveSearch { get; set; } = true;

    internal string ResolveBaseDirectory()
        => string.IsNullOrWhiteSpace(BaseDirectory)
            ? AppContext.BaseDirectory
            : Path.GetFullPath(BaseDirectory);
}