// Copyright 2018 RED Software, LLC. All Rights Reserved.

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

namespace IgniteEngine
{
    /// <summary>
    /// Class to interact with the assembly.
    /// </summary>
    public static class Assembly
    {
        /// <summary>
        /// Represents the assembly's name.
        /// </summary>
        public static string Name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
        /// <summary>
        /// Represents the assembly's version.
        /// </summary>
        public static string Version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(3);

        /// <summary>
        /// Find all methods in the assembly with the specified attribute.
        /// </summary>
        /// <typeparam name="TAttribute">The type of the attribute being searched for.</typeparam>
        /// <returns>A list of all methods with the specified attribute.</returns>
        public static IEnumerable<Tuple<TAttribute, MethodInfo>> GetMethodsWithAttribute<TAttribute>() where TAttribute : Attribute => from Method in AppDomain.CurrentDomain.GetAssemblies()
                .Where(assembly => !assembly.GlobalAssemblyCache)
                .SelectMany(assembly => assembly.GetTypes())
                .SelectMany(type => type.GetMethods())
            let Attribute = Attribute.GetCustomAttribute(Method, typeof(TAttribute), false) as TAttribute
            where Attribute != null
            select new Tuple<TAttribute, MethodInfo>(Attribute, Method);
    }
}
