using System.Reflection;

namespace IceCreamShopContracts.DI
{
    public class ServiceProviderLoader
    {
        /// <summary>
        /// Загрузка всех классов-реализаций IImplementationExtension
        /// </summary>
        /// <returns></returns>
        public static List<IImplementationExtension?> GetImplementationExtensions()
        {
            Type[] handledTypes =
            {
                typeof(IImplementationBusinessLogicExtension),
                typeof(IImplementationExtension)
            };
            var result = handledTypes.Select(x => (IImplementationExtension?)null).ToList();
            var files = Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", SearchOption.AllDirectories);
            foreach (var file in files.Distinct())
            {
                Assembly asm = Assembly.LoadFrom(file);
                foreach (var t in asm.GetExportedTypes())
                {
                    for (var i = 0; i < handledTypes.Length; i++)
                    {
                        if (t.IsClass && handledTypes[i].IsAssignableFrom(t))
                        {
                            if (result[i] == null)
                            {
                                result[i] = (IImplementationExtension)Activator.CreateInstance(t)!;
                            }
                            else
                            {
                                var newSource = (IImplementationExtension)Activator.CreateInstance(t)!;
                                if (newSource.Priority > result[i].Priority)
                                {
                                    result[i] = newSource;
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }

        private static string TryGetImplementationExtensionsFolder()
        {
            var directory = new DirectoryInfo(Directory.GetCurrentDirectory());
            while (directory != null && !directory.GetDirectories("ImplementationExtensions", SearchOption.AllDirectories).Any(x => x.Name == "ImplementationExtensions"))
            {
                directory = directory.Parent;
            }

            return $"{directory?.FullName}\\ImplementationExtensions";
        }
    }
}
