using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQLite
{
    public abstract class SQLiteDbContext
    {
        public List<IDBTable> DbSet = new List<IDBTable>();
        public SQLiteHelper sqliteHelper;
        string ConnectionString
        {
            get
            {
                return string.Format("Data Source={0};Version=3;", DBPath);
            }
        }
        public string DBPath { get; private set; } = @"test.sqlite3";

        public SQLiteDbContext(string dbPath)
        {
            DBPath = dbPath;
            Constructor();
        }
        void Constructor()
        {
            sqliteHelper = new SQLiteHelper();
            sqliteHelper.ConnectionString = ConnectionString;

            var type = GetType();
            foreach (var p in type.GetProperties())
            {
                if (typeof(IDBTable).IsAssignableFrom(p.PropertyType))
                {
                    DbSet.Add(p.GetValue(this) as IDBTable);
                }
            }
            foreach (IDBTable dBTable in DbSet)
            {
                dBTable.Init(sqliteHelper);
            }
        }
        public void SetDBPath(string dbPath)
        {
            DBPath = dbPath;
            sqliteHelper.ConnectionString = ConnectionString;
        }

        void Build()
        {

            string directoryname = System.IO.Path.GetDirectoryName(DBPath);

            if (!string.IsNullOrEmpty(directoryname) && !System.IO.Directory.Exists(directoryname))
                System.IO.Directory.CreateDirectory(directoryname);

            SQLiteConnection.CreateFile(DBPath);

            foreach (IDBTable dBTable in DbSet)
                dBTable.Create();

        }
        void Rebuild()
        {
            if (!System.IO.File.Exists(DBPath))
            {
                Build();
            }
            else
            {
                //把文件删除，重建
                System.IO.File.Delete(DBPath);
                Build();
            }
        }

        void Load()
        {
            foreach(var table in DbSet)
            {
                table.FreeID = LoadID(table.TableName);
            }
        }
        long LoadID(string tablename)
        {
            string cmd = $"SELECT MAX(ID) FROM {tablename}";
            var reponse = sqliteHelper.ExecuteScalar(cmd);
            if (reponse is DBNull)
                return 0;
            else
                return System.Convert.ToInt64(reponse) + 1;

        }

        /// <summary>
        /// 给定分区数 检测表是否存在，合法
        /// </summary>
        /// <param name="nbolts"></param>
        /// <returns>false 表不合法，重建; true 正常！</returns>
        public bool Init()
        {
            if (!System.IO.File.Exists(DBPath))
            {
                Build();
                return false;
            }
            //TODO, 表不对删除就好。。。没必要重新创建数据库

            //任意一个表不对，或者不存在，都必须重建
            Dictionary<string, string> ddls = new Dictionary<string, string>();
            foreach (IDBTable tb in DbSet)
            {
                ddls.Add(tb.TableName, tb.DDL);
            }
            bool isVaild = sqliteHelper.IsTableValid(ddls);



            if (!isVaild)
            {
                Rebuild();
            }
            else
            {
                //加载 
                Load();
            }
            return isVaild;
        }
    }
    
}
