// Copyright © 2017-2018 Atomic Software, LLC. All Rights Reserved.
// See LICENSE.md for full license information.

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

namespace Atom.Core
{
    public static class AtomAssembly
    {
        /// <summary>
        /// Represents the assembly's name.
        /// </summary>
        public static string Name = Assembly.GetEntryAssembly().GetName().Name;
        /// <summary>
        /// Represents the assembly's version.
        /// </summary>
        public static string Version = 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<Pair<TAttribute, MethodInfo>> GetMethodsWithAttribute<TAttribute>() where TAttribute : Attribute
        {
            return 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 Pair<TAttribute, MethodInfo>(Attribute, Method);
        }
    }
}
