using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;

namespace Quanjiang.DigitalScholl.DataSync
{
    public partial class SyncWindow : Form
    {
        public SyncWindow()
        {
            InitializeComponent();
        }
        string _synctype = "";
        Thread thread = null;
        int max = 0;
        public SyncWindow(string synctype)
        {
            _synctype = synctype;
            InitializeComponent();
        }
        
        private void SyncWindow_Load(object sender, EventArgs e)
        {
            this.ControlBox = false;
            progressBar1.Minimum = 0;
            progressBar1.Maximum = max;
            progressBar1.Value = 0;
            if (_synctype == "core")
            {
                ThreadStart start = new ThreadStart(SyncCoreDB);
                thread = new Thread(start);
                thread.Start();
            }
            if (_synctype == "mis")
            {
                ThreadStart start = new ThreadStart(SyncMisDB);
                thread = new Thread(start);
                thread.Start();
            }
        }

        public void SyncCoreDB()
        {
            try
            {
                //获取所有表 core
                MainService mainservice = new MainService();
                SetValueProgressBar(SetValue, 0);
                SetWindowTitle("正在连接数据库...");
                AppendTextValue("正在连接框架源数据库...\r\n");
                //框架源
                Server servercoresource = new Server(new ServerConnection(new SqlConnection(mainservice.GetDataRepository("source").getDbConnection().ConnectionString)));
                AppendTextValue("正在连接框架目标数据库...\r\n");
                Server servercoretarget = new Server(new ServerConnection(new SqlConnection(mainservice.GetDataRepository("target").getDbConnection().ConnectionString)));
                if (servercoresource.Status == ServerStatus.Online)
                {
                    AppendTextValue("框架源数据库连接成功...\r\n");
                }
                if (servercoretarget.Status == ServerStatus.Online)
                {
                    AppendTextValue("框架目标数据库连接成功...\r\n");
                }
                if (servercoresource.Status != ServerStatus.Online || servercoretarget.Status != ServerStatus.Online)
                {
                    AppendTextValue("数据库连接失败,请检查连接字符串或网络环境后重试!\r\n");
                    return;
                }
                Database databasesource = servercoresource.Databases[mainservice.GetDataRepository("source").getDbConnection().Database];
                Database databasetarget = servercoretarget.Databases[mainservice.GetDataRepository("target").getDbConnection().Database];
                TableCollection sourcetables = databasesource.Tables;
                TableCollection targettables = databasetarget.Tables;
                SetWindowTitle("正在同步框架表结构...");
                AppendTextValue("正在同步框架表结构...\r\n");
                AppendTextValue("本次同步框架表结构共" + sourcetables.Count + "个表...\r\n");
                SetProgressMax(sourcetables.Count);
                foreach (Table sourcetable in sourcetables)
                {
                    AppendTextValue("正在检测" + sourcetable.Name + "表结构...\r\n");
                    SetValueProgressBar(SetValue, GetProgressValue()+1);
                    if (Program.beginTable != "")
                    {
                        if(sourcetable.Name!=Program.beginTable)
                            continue;
                    }
                    if (targettables.Contains(sourcetable.Name))
                    {
                        ColumnCollection sourcecolumns = sourcetable.Columns;
                        foreach (Column sourcecolumn in sourcecolumns)
                        {
                            //检查字段是否包含
                            if (targettables[sourcetable.Name].Columns.Contains(sourcecolumn.Name))
                            {
                                //检查数据类型
                                if (targettables[sourcetable.Name].Columns[sourcecolumn.Name].DataType.Equals(sourcecolumn.DataType))
                                {
                                    continue;
                                }
                                else
                                {
                                    //修改数据类型
                                    databasetarget.Tables[sourcetable.Name].Columns[sourcecolumn.Name].DataType = sourcecolumn.DataType;
                                    databasetarget.Tables[sourcetable.Name].Alter();
                                }
                            }
                            else
                            {
                                Column colmiss = new Column(databasetarget.Tables[sourcetable.Name], sourcecolumn.Name, sourcecolumn.DataType);
                                colmiss.Collation = sourcecolumn.Collation;
                                colmiss.Nullable = sourcecolumn.Nullable;
                                colmiss.Identity = sourcecolumn.Identity;
                                colmiss.Default = sourcecolumn.Default;
                                foreach (ExtendedProperty property in sourcecolumn.ExtendedProperties)
                                {
                                    colmiss.ExtendedProperties.Add(new ExtendedProperty(colmiss,property.Name,property.Value));
                                }
                                databasetarget.Tables[sourcetable.Name].Columns.Add(colmiss);
                                databasetarget.Tables[sourcetable.Name].Alter();
                            }
                        }

                    }
                    else
                    {
                        //初始化Scripter 
                        ScriptingOptions scriptingOptions = new ScriptingOptions();
                        scriptingOptions.Add(ScriptOption.DriAllConstraints);
                        scriptingOptions.Add(ScriptOption.DriAllKeys);
                        scriptingOptions.Add(ScriptOption.Default);
                        scriptingOptions.Add(ScriptOption.ContinueScriptingOnError);
                        scriptingOptions.Add(ScriptOption.ConvertUserDefinedDataTypesToBaseType);
                        scriptingOptions.Add(ScriptOption.IncludeIfNotExists);
                        scriptingOptions.Add(ScriptOption.DriPrimaryKey);
                        scriptingOptions.Add(ScriptOption.ExtendedProperties);
                        StringCollection sc= sourcetable.Script(scriptingOptions);
                        StringBuilder sb=new StringBuilder();
                        foreach (var s in sc)
                        {
                            sb.Append(s+"\r\n");
                        }
                        //新建表
                        mainservice.GetDataRepository("target").ExecuteBySql(sb.ToString());
                    }
                }
                AppendTextValue("正在保存表结构,请耐心等待...\r\n");
                CloseWindow();
            }
            catch (Exception e)
            {
                AppendTextValue("error:" + e.Message + "\r\n");
            }

        }
        public void SyncMisDB()
        {
            try
            {
                //获取所有表 core
                MainService mainservice = new MainService();
                SetValueProgressBar(SetValue, 0);
                SetWindowTitle("正在连接数据库...");
                AppendTextValue("正在连接mis源数据库...\r\n");
                //框架源
                Server servercoresource = new Server(new ServerConnection(new SqlConnection(mainservice.GetDataRepository("missource").getDbConnection().ConnectionString)));
                AppendTextValue("正在连接mis目标数据库...\r\n");
                Server servercoretarget = new Server(new ServerConnection(new SqlConnection(mainservice.GetDataRepository("mistarget").getDbConnection().ConnectionString)));
                if (servercoresource.Status == ServerStatus.Online)
                {
                    AppendTextValue("mis源数据库连接成功...\r\n");
                }
                if (servercoretarget.Status == ServerStatus.Online)
                {
                    AppendTextValue("mis目标数据库连接成功...\r\n");
                }
                if (servercoresource.Status != ServerStatus.Online || servercoretarget.Status != ServerStatus.Online)
                {
                    AppendTextValue("数据库连接失败,请检查连接字符串或网络环境后重试!\r\n");
                    return;
                }
                Database databasesource = servercoresource.Databases[mainservice.GetDataRepository("missource").getDbConnection().Database];
                Database databasetarget = servercoretarget.Databases[mainservice.GetDataRepository("mistarget").getDbConnection().Database];
                TableCollection sourcetables = databasesource.Tables;
                TableCollection targettables = databasetarget.Tables;
                SetWindowTitle("正在同步mis表结构...");
                AppendTextValue("正在同步mis表结构...\r\n");
                AppendTextValue("本次同步mis表结构共" + sourcetables.Count + "个表...\r\n");
                SetProgressMax(sourcetables.Count);
                foreach (Table sourcetable in sourcetables)
                {
                    AppendTextValue("正在检测" + sourcetable.Name + "表结构...\r\n");
                    SetValueProgressBar(SetValue, GetProgressValue() + 1);
                    if (Program.beginTable != "")
                    {
                        if (sourcetable.Name != Program.beginTable)
                            continue;
                    }
                    if (targettables.Contains(sourcetable.Name))
                    {
                        ColumnCollection sourcecolumns = sourcetable.Columns;
                        foreach (Column sourcecolumn in sourcecolumns)
                        {
                            //检查字段是否包含
                            if (targettables[sourcetable.Name].Columns.Contains(sourcecolumn.Name))
                            {
                                //检查数据类型
                                if (targettables[sourcetable.Name].Columns[sourcecolumn.Name].DataType.Equals(sourcecolumn.DataType))
                                {
                                    continue;
                                }
                                else
                                {
                                    //修改数据类型
                                    databasetarget.Tables[sourcetable.Name].Columns[sourcecolumn.Name].DataType = sourcecolumn.DataType;
                                    databasetarget.Tables[sourcetable.Name].Alter();
                                }
                            }
                            else
                            {
                                Column colmiss = new Column(databasetarget.Tables[sourcetable.Name], sourcecolumn.Name, sourcecolumn.DataType);
                                colmiss.Collation = sourcecolumn.Collation;
                                colmiss.Nullable = sourcecolumn.Nullable;
                                colmiss.Identity = sourcecolumn.Identity;
                                colmiss.Default = sourcecolumn.Default;
                                foreach (ExtendedProperty property in sourcecolumn.ExtendedProperties)
                                {
                                    colmiss.ExtendedProperties.Add(new ExtendedProperty(colmiss, property.Name, property.Value));
                                }
                                databasetarget.Tables[sourcetable.Name].Columns.Add(colmiss);
                                databasetarget.Tables[sourcetable.Name].Alter();
                            }
                        }

                    }
                    else
                    {
                        //初始化Scripter 
                        ScriptingOptions scriptingOptions = new ScriptingOptions();
                        scriptingOptions.Add(ScriptOption.DriAllConstraints);
                        scriptingOptions.Add(ScriptOption.DriAllKeys);
                        scriptingOptions.Add(ScriptOption.Default);
                        scriptingOptions.Add(ScriptOption.ContinueScriptingOnError);
                        scriptingOptions.Add(ScriptOption.ConvertUserDefinedDataTypesToBaseType);
                        scriptingOptions.Add(ScriptOption.IncludeIfNotExists);
                        scriptingOptions.Add(ScriptOption.DriPrimaryKey);
                        scriptingOptions.Add(ScriptOption.ExtendedProperties);
                        StringCollection sc = sourcetable.Script(scriptingOptions);
                        StringBuilder sb = new StringBuilder();
                        foreach (var s in sc)
                        {
                            sb.Append(s + "\r\n");
                        }
                        //新建表
                        mainservice.GetDataRepository("mistarget").ExecuteBySql(sb.ToString());
                    }
                }
                AppendTextValue("正在保存表结构,请耐心等待...\r\n");
                CloseWindow();
            }
            catch (Exception e)
            {
                AppendTextValue("error:" + e.Message + "\r\n");
            }
        }

        #region 委托

        public delegate void AppendTextValueDelegate(string text);
        public delegate void SetValueDelegate(int val);
        public delegate void CloseWindowDelegate();
        public delegate void SetWindowTitleDelegate(string text);
        public delegate int GetProgressValueDelegate();
        public delegate void SetProgressMaxDelegate(int max);
        public void AppendTextValue(string text)
        {
            if (this.rtblog.InvokeRequired)
            {
                AppendTextValueDelegate callback = new AppendTextValueDelegate(AppendTextValue);
                this.Invoke(callback, text);
            }
            else
            {
                rtblog.AppendText(text);
                
            }
        }
        public void SetProgressMax(int max)
        {
            if (this.progressBar1.InvokeRequired)
            {
                SetProgressMaxDelegate callback = new SetProgressMaxDelegate(SetProgressMax);
                this.Invoke(callback, max);
            }
            else
            {
                progressBar1.Maximum = max;
            }
        }
        public int GetProgressValue()
        {
            if (this.progressBar1.InvokeRequired)
            {
                GetProgressValueDelegate callback = new GetProgressValueDelegate(GetProgressValue);
                return Convert.ToInt32(this.Invoke(callback));
            }
            else
            {
                return progressBar1.Value;
            }
        }
        public void SetWindowTitle(string text)
        {
            if (this.InvokeRequired)
            {
                SetWindowTitleDelegate callback = new SetWindowTitleDelegate(SetWindowTitle);
                this.Invoke(callback, text);
            }
            else
            {
                this.Text = text;
            }
        }
        public void CloseWindow()
        {
            if (this.InvokeRequired)
            {
                CloseWindowDelegate callback = new CloseWindowDelegate(CloseWindow);
                this.Invoke(callback);
            }
            else
            {
                this.Close();
            }

        }
        public void SetValue(int val)
        {
            progressBar1.Value = val;
        }
        public void SetValueProgressBar(SetValueDelegate myDelegate, int val)
        {
            if (this.progressBar1.InvokeRequired)
            {
                this.Invoke(myDelegate, val);
            }
            else
            {
                myDelegate(val);
            }
        }
        #endregion

        private void btcancelsync_Click(object sender, EventArgs e)
        {
            CloseWindow();
        }
    }
}