using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Fasterflect;

namespace LeafWeb.Core.Utility
{
	public static class ReflectionExtensions
	{
		public static string GetPropertyDisplayName<T>(Expression<Func<T, object>> propertyExpression)
		{
			var memberInfo = GetPropertyInformation(propertyExpression.Body);
			if (memberInfo == null)
			{
				throw new ArgumentException("No property reference expression was found.", nameof(propertyExpression));
			}

			var attr = memberInfo.Attributes<DisplayNameAttribute>().SingleOrDefault();
			return attr == null ? memberInfo.Name : attr.DisplayName;
		}
		
		public static MemberInfo GetPropertyInformation(Expression propertyExpression)
		{
			Debug.Assert(propertyExpression != null, "propertyExpression != null");
			var memberExpr = propertyExpression as MemberExpression;
			if (memberExpr == null)
			{
				var unaryExpr = propertyExpression as UnaryExpression;
				if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
				{
					memberExpr = unaryExpr.Operand as MemberExpression;
				}
			}

			if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
			{
				return memberExpr.Member;
			}

			return null;
		}
	}
}