using System.Collections.Concurrent;
using e_suite.Workflow.Core.Attributes;
using e_suite.Workflow.Core.Interfaces;

namespace e_suite.Workflow.Core.Extensions;

public static class StageExtensions
{
    public static bool CanComplete<T>(this IStage<T> stage)
        where T : TaskTypeAttribute
    {
        return stage.Tasks.All(x =>
            x.IsCompleted());
    }

    private static readonly ConcurrentDictionary<Type, IEnumerable<Type>> AllowedTasksCache = new();

    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "Style", "IDE0305:Collection initialization can be simplified",
        Justification = "Materialization required for caching")]
    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "Style", "IDE0060:Removed unused parameter 'stage' if it is not part of a shipped public API",
        Justification = "parameter required for extension method definition")]
    public static IEnumerable<Type> AllowedTasks<T>(this IStage<T> stage)
        where T : TaskTypeAttribute
    {
        var attributeType = typeof(T);

        return AllowedTasksCache.GetOrAdd(attributeType, _ =>
        {
            return AppDomain.CurrentDomain
                .GetAssemblies()
                .SelectMany(a =>
                {
                    try { return a.GetTypes(); }
                    catch { return []; }
                })
                .Where(t =>
                    t.IsClass &&
                    !t.IsAbstract &&
                    t.GetCustomAttributes(attributeType, inherit: true).Length != 0)
                .ToArray();
        });
    }
}