namespace CommonLibrary
{
    using System;
    using System.Data.SqlClient;
    using MySql.Data.MySqlClient;

    public enum DBTYPE
    {
        Mysql,
        Sqlserver,
    }

    public static class DatabaseUtil
    {
        /// TODO:需要进行测试
        /// <summary>
        /// 备份、还原数据库的接口
        /// </summary>
        /// <param name="type">Mysql、Sql Sever数据库</param>
        /// <param name="blBackOrRestore">true:备份;false:还原</param>
        /// <param name="connectionString">连接数据库字符串</param>
        /// <param name="filePath">备份或还原的路径</param>
        /// <returns>是否成功</returns>
        public static bool Action(DBTYPE type, bool blBackOrRestore, string connectionString, string filePath)
        {
            if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            if (blBackOrRestore)
            {
                if (type == DBTYPE.Mysql)
                {
                    return MysqlBackup(connectionString, filePath);
                }
                else if (type == DBTYPE.Sqlserver)
                {
                    return SqlserverBackup(connectionString, filePath);
                }
            }
            else
            {
                if (type == DBTYPE.Mysql)
                {
                    return MysqlRestore(connectionString, filePath);
                }
                else if (type == DBTYPE.Sqlserver)
                {
                    return SqlserverRestore(connectionString, filePath);
                }
            }

            return true;
        }

        private static bool MysqlBackup(string connectionString, string filePath)
        {
            if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            try
            {
                using (MySqlConnection conn = new MySqlConnection(filePath))
                {
                    using (MySqlCommand cmd = new MySqlCommand())
                    {
                        using (MySqlBackup mb = new MySqlBackup(cmd))
                        {
                            cmd.Connection = conn;
                            conn.Open();
                            mb.ExportToFile(filePath);
                            conn.Close();
                        }
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

        private static bool MysqlRestore(string connectionString, string filePath)
        {
            if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            try
            {
                using (MySqlConnection conn = new MySqlConnection(connectionString))
                {
                    using (MySqlCommand cmd = new MySqlCommand())
                    {
                        using (MySqlBackup mb = new MySqlBackup(cmd))
                        {
                            cmd.Connection = conn;
                            conn.Open();
                            mb.ImportFromFile(filePath);
                            conn.Close();
                        }
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

        private static string Cut(string str, string bg, string ed)
        {
            string sub = str.Substring(str.IndexOf(bg) + bg.Length);
            sub = sub.Substring(0, sub.IndexOf(";"));

            return sub;
        }

        private static bool SqlserverBackup(string connectionString, string filePath)
        {
            if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            try
            {
                string database = Cut(connectionString, "database=", ";");

                string sql = "BACKUP DATABASE " + database + " to DISK = '" + filePath + "'";

                using (SqlConnection conn = new SqlConnection(connectionString))
                {
                    conn.Open();
                    using (SqlCommand cmd = new SqlCommand(sql, conn))
                    {
                        cmd.ExecuteNonQuery();
                        conn.Close();
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }

        private static bool SqlserverRestore(string connectionString, string filePath)
        {
            if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            try
            {
                string database = Cut(connectionString, "database=", ";");

                using (SqlConnection conn = new SqlConnection(connectionString))
                {
                    conn.Open();
                    string sqlStmt2 = string.Format("ALTER DATABASE [" + database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
                    SqlCommand bu2 = new SqlCommand(sqlStmt2, conn);
                    bu2.ExecuteNonQuery();

                    string sqlStmt3 = "USE MASTER RESTORE DATABASE [" + database + "] FROM DISK='" + filePath + "'WITH REPLACE;";
                    SqlCommand bu3 = new SqlCommand(sqlStmt3, conn);
                    bu3.ExecuteNonQuery();

                    string sqlStmt4 = string.Format("ALTER DATABASE [" + database + "] SET MULTI_USER");
                    SqlCommand bu4 = new SqlCommand(sqlStmt4, conn);
                    bu4.ExecuteNonQuery();

                    conn.Close();
                }
            }
            catch (Exception)
            {
                return false;
            }

            return true;
        }
    }
}
