using Ant.DbExpressions;
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Threading;
using Ant.Core;
using Ant.Core.Emit;
using Ant.ORM;

namespace Ant.Descriptors
{
    public class PropertyDescriptor : MappingMemberDescriptor
    {
        PropertyInfo _propertyInfo;
        DbColumn _column;

        Func<object, object> _valueGetter = null;
        Action<object, object> _valueSetter = null;
        public PropertyDescriptor(PropertyInfo propertyInfo, FiledMetaData declaringEntityDescriptor, string columnName)
            : base(declaringEntityDescriptor)
        {
            this._propertyInfo = propertyInfo;
            this._column = new DbColumn(columnName, propertyInfo.PropertyType);
        }
        /// <summary>
        /// 获取有关成员特性的信息并提供对成员元数据的访问
        /// </summary>
        public override MemberInfo MemberInfo
        {
            get { return this._propertyInfo; }
        }
        /// <summary>
        ///  表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型
        /// </summary>
        public override Type MemberInfoType
        {
            get { return this._propertyInfo.PropertyType; }
        }
        /// <summary>
        /// 标记每个已定义为 MemberInfo 的派生类的成员类型
        /// </summary>
        public override MemberTypes MemberType
        {
            get { return MemberTypes.Property; }
        }
        /// <summary>
        /// 
        /// </summary>
        public override DbColumn Column
        {
            get { return this._column; }
        }
        /// <summary>
        /// 获取列的值
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public override object GetValue(object instance)
        {
            if (null == this._valueGetter)
            {
                if (Monitor.TryEnter(this))
                {
                    try
                    {
                        if (null == this._valueGetter)
                        {
                            this._valueGetter = DelegateGenerator.CreateValueGetter(this._propertyInfo);
                        }
                    }
                    finally
                    {
                        Monitor.Exit(this);
                    }
                }
                else
                {
                    return this._propertyInfo.GetValue(instance, null);
                }
            }

            return this._valueGetter(instance);
        }
        /// <summary>
        /// 给列进行赋值
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="value"></param>
        public override void SetValue(object instance, object value)
        {
            if (null == this._valueSetter)
            {
                if (Monitor.TryEnter(this))
                {
                    try
                    {
                        if (null == this._valueSetter)
                        {
                            this._valueSetter = DelegateGenerator.CreateValueSetter(this._propertyInfo);
                        }
                    }
                    finally
                    {
                        Monitor.Exit(this);
                    }
                }
                else
                {
                    this._propertyInfo.SetValue(instance, value, null);
                    return;
                }
            }

            this._valueSetter(instance, value);
        }
    }

}