using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;


namespace NBF
{
    public static class Reflection
    {
        private static readonly Assembly _assembly;

        public static Assembly Assembly => _assembly;

        static Reflection()
        {
            _assembly = AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "Assembly-CSharp");
            Types = _assembly.GetTypes();
        }

        public static Type[] Types { get; private set; }

        /// <summary>
        /// 获取所有非抽象的派生类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<Type> GetAllNonAbstractDerivedTypes<T>()
        {
            Type baseType = typeof(T);
            Assembly assembly = Assembly.GetAssembly(baseType);

            List<Type> derivedTypes = assembly.GetTypes()
                .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(baseType))
                .ToList();

            return derivedTypes;
        }


        /// <summary>
        /// 获取所有标记指定特性的方法
        /// </summary>
        /// <param name="classType">查找类</param>
        /// <param name="attributeType">特性类</param>
        /// <returns></returns>
        public static List<MethodInfo> GetMethodsWithUIInputAttribute(Type classType, Type attributeType)
        {
            List<MethodInfo> methodsWithAttribute = new List<MethodInfo>();

            if (classType == null)
            {
                return methodsWithAttribute;
            }

            // 获取所有方法，包括公共、非公共、实例和静态方法
            MethodInfo[] allMethods =
                classType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (MethodInfo method in allMethods)
            {
                if (method.GetCustomAttributes(attributeType, false).Length > 0)
                {
                    methodsWithAttribute.Add(method);
                }
            }

            return methodsWithAttribute;
        }

        /// <summary>
        /// 获取所有标记指定特性的方法
        /// </summary>
        /// <param name="classType">查找类</param>
        /// <returns></returns>
        public static Dictionary<MethodInfo, T> GetMethodsAttribute<T>(Type classType) where T : Attribute
        {
            Dictionary<MethodInfo, T> methodsWithAttribute = new Dictionary<MethodInfo, T>();

            if (classType == null)
            {
                return methodsWithAttribute;
            }

            // 获取所有方法，包括公共、非公共、实例和静态方法
            MethodInfo[] allMethods =
                classType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (MethodInfo method in allMethods)
            {
                var attribute = method.GetCustomAttribute<T>();
                if (attribute != null)
                {
                    methodsWithAttribute[method] = attribute;
                }
            }

            return methodsWithAttribute;
        }
    }
}