using System.Linq.Expressions;
using System.Reflection;

namespace Pilz.Extensions.Reflection;

public static class MethodInfoExtensions
{
    /// <summary>
    /// Source: https://stackoverflow.com/questions/940675/getting-a-delegate-from-methodinfo
    /// </summary>
    /// <param name="methodInfo"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    public static Delegate CreateDelegate(this MethodInfo methodInfo, object? target)
    {
        var parmTypes = methodInfo.GetParameters().Select(parm => parm.ParameterType);
        var parmAndReturnTypes = parmTypes.Append(methodInfo.ReturnType).ToArray();
        var delegateType = Expression.GetDelegateType(parmAndReturnTypes);

        if (methodInfo.IsStatic)
            return methodInfo.CreateDelegate(delegateType);
        return methodInfo.CreateDelegate(delegateType, target);
    }
}
