using System;
using System.Collections.Generic;
using System.Reflection;
namespace Apewer.Source
{
    /// 索引。
    [Serializable]
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
    public sealed class IndexAttribute : Attribute, IToJson
    {
        PropertyInfo _property = null;
        ColumnAttribute _column;
        string _name = null;
        FieldOrder _order = FieldOrder.Ascend;
        /// 索引名称。
        public string Name { get => _name; }
        /// 排序。
        public FieldOrder Order { get => _order; set => _order = value; }
        /// 列。
        public ColumnAttribute Column { get => _column; }
        /// 属性。
        public PropertyInfo Property { get => _property; }
        /// 表示此属性是索引的一部分。
        /// 索引名称。
        public IndexAttribute(string name)
        {
            if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
            _name = name;
        }
        internal void SetColumn(ColumnAttribute column)
        {
            _column = column;
        }
        /// 解析列的索引。
        /// 注意:此方法不再抛出异常,当不存在正确的列特性时将返回 NULL 值
        public static IndexAttribute[] Parse(PropertyInfo property)
        {
            if (property == null) return null;
            var attributes = property.GetCustomAttributes(typeof(IndexAttribute), true);
            var ias = new List();
            foreach (var attribute in attributes)
            {
                var ia = attribute as IndexAttribute;
                if (ia == null) continue;
                if (ia._name.IsEmpty()) continue;
                ia._property = property;
                ias.Add(ia);
            }
            return ias.ToArray();
        }
        /// 生成 Json 对象。
        /// 
        public Json ToJson()
        {
            var json = Json.NewObject();
            json.SetProperty("name", _name);
            json.SetProperty("order", _order.ToString());
            if (_column != null) json.SetProperty("column", _column.ToJson());
            return json;
        }
        /// 
        public override string ToString() => $"Index = {_name}, Field = {_column?.Field}, Order = {_order}";
    }
}