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

namespace Apewer.Source
{

    /// <summary>数据库记录通用字段模型。</summary>
    [Serializable]
    public class Record : IRecord
    {

        private const int DefaultLength = 191;
        private const int KeyLength = 128;

        [NonSerialized]
        private string _created = "";

        [NonSerialized]
        private string _updated = "";

        [NonSerialized]
        private long _flag = 0;

        [NonSerialized]
        private string _remark = "";

        [NonSerialized]
        private string _key = GenerateKey();

        /// <summary>记录的创建时间,值为执行 INSERT INTO 语句时的时间。</summary>
        [Column("_created", ColumnType.NVarChar, DefaultLength)]
        public virtual string Created { get { return _created; } set { _created = TextModifier.Compact(value, DefaultLength); } }

        /// <summary>记录的更新时间,类型,每次对此记录执行 UPDATE 时应更新此值为当前系统时间。</summary>
        [Column("_updated", ColumnType.NVarChar, DefaultLength)]
        public virtual string Updated { get { return _updated; } set { _updated = TextModifier.Compact(value, DefaultLength); } }

        /// <summary>记录的标记,Int64 类型,区分记录的状态。</summary>
        [Column("_flag", ColumnType.Integer)]
        public virtual long Flag { get { return _flag; } set { _flag = value; } }

        /// <summary>备注,NText 类型。</summary>
        [Column("_remark", ColumnType.NText)]
        public virtual string Remark { get { return _remark; } set { _remark = TextModifier.Compact(value); } }

        /// <summary>记录唯一键,一般使用 GUID 的字符串形式。</summary>
        [Column("_key", ColumnType.NVarChar, KeyLength)]
        public virtual string Key { get { return _key; } set { _key = TextModifier.Compact(value, KeyLength); } }

        /// <summary>重置主键。</summary>
        internal static void ResetKey(Record record)
        {
            if (record == null) return;
            record.Key = GenerateKey();
        }

        /// <summary>生成新主键。</summary>
        public static string GenerateKey() => Guid.NewGuid().ToString().ToLower().Replace("-", "");

        internal static void FixProperties(Record record)
        {
            if (record == null) return;

            if (record.Flag == 0) record.Flag = 1;
            if (TextUtility.IsBlank(record.Key)) record.Key = TextUtility.NewGuid();

            var now = ClockUtility.LucidNow;
            if (TextUtility.IsBlank(record.Created)) record.Created = now;
            if (TextUtility.IsBlank(record.Updated)) record.Updated = now;
        }

        /// <summary>枚举带有 Table 特性的 <typeparamref name="T"/> 派生类型。</summary>
        public static List<Type> EnumerateTableTypes<T>() where T : Record
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            var list = new List<Type>();
            foreach (var a in assemblies)
            {
                var types = RuntimeUtility.GetTypes(a);
                foreach (var t in types)
                {
                    if (!EnumerateTableTypes(t, typeof(T))) continue;
                    if (list.Contains(t)) continue;
                    list.Add(t);
                }
            }
            return list;
        }

        private static bool EnumerateTableTypes(Type type, Type @base)
        {
            if (type == null || @base == null) return false;
            if (!type.IsAbstract)
            {
                if (RuntimeUtility.ContainsAttribute<TableAttribute>(type, false))
                {
                    if (type.Equals(@base))
                    {
                        return true;
                    }
                    else
                    {
                        if (RuntimeUtility.IsInherits(type, @base)) return true; ;
                    }
                }
            }
            return false;
        }

    }

}