using Apewer.Internals;
using System;
using System.Collections.Generic;
using System.Text;

namespace Apewer.Source
{

    /// <summary>数据库中的表。</summary>
    /// <remarks>
    /// <para>Name: 数据库的表名。</para>
    /// <para>Store: 数据存储区名称。</para>
    /// </remarks>
    [Serializable]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
    public sealed class TableAttribute : Attribute
    {

        private string _name;
        private string _store;

        /// <summary>标记表属性。</summary>
        public TableAttribute(string name = null, string store = null)
        {
            _name = TableStructure.RestrictName(name, string.IsNullOrEmpty(name));
            _store = string.IsNullOrEmpty(store) ? null : TableStructure.RestrictName(store, false);
        }

        /// <summary>表名。</summary>
        public string Name { get => _name; }

        /// <summary>存储名。</summary>
        public string Store { get => _store; }

        /// <summary>表的说明信息。(需要数据库客户端支持)</summary>
        public string Description { get; set; }

        /// <summary>独立结构,不依赖 Record 公共属性。</summary>
        internal bool Independent { get; set; }

        /// <summary>使用模型的所有属性,对缺少 Column 特性的属性使用默认参数的 Column 特性。</summary>
        public bool AllProperties { get; set; }

        private static Dictionary<string, TableAttribute> _tac = new Dictionary<string, TableAttribute>();

        /// <summary>解析表特性,默认使用缓存以提升性能。</summary>
        public static TableAttribute Parse<T>(bool useCache = true) where T : IRecord => Parse(typeof(T), useCache);

        /// <summary>解析表特性,默认使用缓存以提升性能。</summary>
        public static TableAttribute Parse(Type type, bool useCache = true)
        {
            var cacheKey = type.FullName;
            if (useCache)
            {
                var hint = null as TableAttribute;
                lock (_tac)
                {
                    if (_tac.ContainsKey(cacheKey))
                    {
                        hint = _tac[cacheKey];
                    }
                }
                if (hint != null) return hint;
            }

            // throw new Exception($"类型 {type.FullName} 不包含 {typeof(TableAttribute).FullName}。");
            var tas = type.GetCustomAttributes(typeof(TableAttribute), false);
            if (tas.LongLength < 1L) return null;

            var ta = (TableAttribute)tas[0];
            if (string.IsNullOrEmpty(ta.Name)) ta._name = "_" + type.Name;
            ta.Independent = RuntimeUtility.Contains<IndependentAttribute>(type, true);

            if (useCache)
            {
                lock (_tac)
                {
                    if (!_tac.ContainsKey(cacheKey)) _tac.Add(cacheKey, ta);
                }
            }

            return ta;
        }

    }

}