using System;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Text.RegularExpressions;

namespace ynhtm.DBUtility
{
    public class SQLiteDb : DbBase
    {
        SQLiteConnection connection = null;
        string dataSource;

        public SQLiteDb()
            : this(DbBase.CONNECTIONSTRING)
        { }

        public SQLiteDb(string connectionString)
        {
            this.ConnectionString = connectionString;
            this.dataSource = Regex.Replace(new SQLiteConnectionStringBuilder(connectionString).DataSource, @"\|DataDirectory\|", AppDomain.CurrentDomain.BaseDirectory + "App_Data", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        }

        public override IDbConnection Connection
        {
            get
            {
                if (connection == null) this.connection = new SQLiteConnection(this.ConnectionString);
                return this.connection;
            }
        }

        public override string IDentity
        {
            get { return "SELECT last_insert_rowid()"; }
        }

        public override string IsNull
        {
            get { return "ifnull"; }
        }

        public override string Now
        {
            get { return "(datetime(CURRENT_TIMESTAMP,'localtime'))"; }
        }

        public string ConnectionString { get; private set; }

        public override IDataParameter CreateParameter(string name, object value)
        {
            return new SQLiteParameter("@" + name, value == null ? DBNull.Value : value);
        }

        protected override DataTable GetPagex(ref int recordCount, string table, string order, int pageSize, int pageIndex, string query, string field)
        {
            base.Open();
            if (!string.IsNullOrEmpty(query)) query = " WHERE " + query;
            using (var cmd = base.CreateCommand("SELECT COUNT(0) FROM " + table + query))
                recordCount = Convert.ToInt32(cmd.ExecuteScalar());
            using (var cmd = base.CreateCommand("SELECT " + field + " FROM " + table + query + " " + order + " LIMIT " + pageSize + " OFFSET " + ((pageIndex - 1) * pageSize)))
            {
                using (var reader = cmd.ExecuteReader())
                {
                    var result = new DataTable();
                    result.Load(reader);
                    return result;
                }
            }
        }

        protected override DataTable GetPagex(string table, string order, int pageSize, int pageIndex, string query, string field)
        {
            if (!string.IsNullOrEmpty(query)) query = " WHERE " + query;
            using (var cmd = base.CreateCommand("SELECT " + field + " FROM " + table + query + " " + order + " LIMIT " + pageSize + " OFFSET " + ((pageIndex - 1) * pageSize)))
            {
                base.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    var result = new DataTable();
                    result.Load(reader);
                    return result;
                }
            }
        }

        public override void Backup(string path)
        {
            File.Copy(this.dataSource, path);
        }

        public override string Name
        {
            get { return this.dataSource; }
        }

        public override string Size
        {
            get { return new FileInfo(this.dataSource).Length.ToString(); }
        }

        public override string Version
        {
            get
            {
                using (var cmd = base.CreateCommand("SELECT sqlite_version()"))
                {
                    base.Open();
                    return cmd.ExecuteScalar().ToString();
                }
            }
        }
    }
}
