using System;
using System.Collections.Generic;
using XGame.Framework.Asyncs;
using XGame.Framework.Serialization;

namespace XGame.Framework.Database
{
    public abstract class TableRepository<TTable, TRepository> : ISerializable, IDisposable where TTable : class, ITable where TRepository : TableRepository<TTable, TRepository>
    {
        protected TTable[] _tables;
        protected Dictionary<long, TTable> _tableMap;

        void ISerializable.Deserialize(IReader reader)
        {
            _tables = reader.ReadEnumerable<TTable[]>();
            _tableMap = new Dictionary<long, TTable>();
            foreach(var table in _tables)
            {
                _tableMap.Add(table.Key, table);
            }
        }

        void ISerializable.Serialize(IWriter writer)
        {
            writer.Write(_tables);
        }

        void IDisposable.Dispose()
        {
            _tables = null;
            _tableMap?.Clear();
            _tableMap = null;
        }

        public TTable GetByKey(long key)
        {
            if (_tableMap == null)
            {
                return default;
            }
            _tableMap.TryGetValue(key, out var table);
            return table;
        }
        public TTable[] GetAllTables()
        {
            if (_tables == null)
            {
                return default;
            }
            return _tables;
        }

        #region 静态方法
        public static string TableName => typeof(TTable).Name;
        public static TTable Get(long key)
        {
            return DatabaseModule.Instance.GetByKey<TTable, TRepository>(key);
        }
        public static TTable[] GetAll()
        {
            return DatabaseModule.Instance.GetAll<TTable, TRepository>();
        }
        public static IAsync LoadAsync()
        {
            return DatabaseModule.Instance.LoadAsync<TTable, TRepository>(TableName);
        }
        public static void Unload()
        {
            DatabaseModule.Instance.Unload(TableName);
        }

        //public static implicit operator TableRepository<TTable>(TableRepository<ITable> v)
        //{
        //    return v as TableRepository<TTable>;
        //}
        #endregion

    }
}
