using Tiobon.Core.OPS.Tool.OPS.Tool.Helper;
using Tiobon.Core.OPS.Tool.OPS.Tool.Model;
using Tiobon.Core.OPS.Tool.OPS.Tool.src;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Data;
using System.Xml;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Core;
using System.Threading.Tasks;
using Renci.SshNet;
using YamlDotNet.Serialization;
using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Tiobon.Core.OPS.Tool.OPS.Tool.Src
{
    public class Main_method
    {
        #region 全局变量
        public SSHHelper sSH;
        public SFTPHelper sFTP;
        bool isupdate = false;
        bool isLinux = Const.config.system == "Linux";
        Dictionary<string, Module> dic_module = new Dictionary<string, Module>();
        bool isInit = false;
        PerformanceCounter cpuCounter;
        PerformanceCounter memoryCounter;
        CounterSample cpuSample1;
        public Action<bool> End_Init;
        private string defaultSubnet = "172.210.238.0";
        #endregion

        #region 获取系统状态
        public string Get_sysstatus()
        {
            if (isInit)
            {
                try
                {

                    if (Const.config.system == "Linux")
                    {
                        if (!sSH.Connected)
                        {
                            Init();
                        }
                        var flag = sSH.Excute_Longcmd("cpu=`vmstat | awk  'NR==3{print $15}'`\n total_mem=`vmstat -s | awk 'NR==1{print $1}'` \n free_mem=`vmstat -s | awk 'NR==5{print $1}'` \n disk=`df  --block-size 1g -h  / | sed -n \"2, 1p\" |awk '{{print $5}}'` \n echo \"$cpu,$total_mem,$free_mem,$disk\"", out string result);
                        if (!flag)
                        {
                            return $"获取系统状态失败：{result}";
                        }
                        var tmp = result.Split(',');
                        var mem = (Math.Round((double.Parse(tmp[1]) - double.Parse(tmp[2])) / double.Parse(tmp[1]), 4) * 100).ToString();
                        return $"   CPU使用：{100 - int.Parse(tmp[0].Trim())}%  内存使用：{mem}%  硬盘使用：{tmp[3].Trim()}";
                    }
                    else
                    {
                        return GetCpuUsage();
                    }
                }
                catch (Exception ex)
                {
                    return $"获取系统状态失败";
                }
            }
            return "";
        }
        #endregion

        #region 获取Windows系统状态
        public string GetCpuUsage()
        {
            double dist = 0;
            double distsum = 0;
            DriveInfo[] drive = DriveInfo.GetDrives();//获取所有驱动器
            foreach (DriveInfo df in drive)//遍历驱动器
            {
                dist += ((df.TotalSize - df.TotalFreeSpace) / 1024 / 1024 / 1024.0);
                distsum += (df.TotalSize / 1024 / 1024 / 1024.0);
            }
            var distinfo = (dist / distsum).ToString("0.00" + "%");

            //float cpusum = 0;
            //foreach (var item in counters)
            //{
            //    cpusum += item.NextValue();
            //}
            var cpuinfo = CounterSampleCalculator.ComputeCounterValue(cpuSample1, cpuCounter.NextSample()).ToString("0.00");
            cpuSample1 = cpuCounter.NextSample();
            return $"CPU使用：{cpuinfo}%  内存使用：{(memoryCounter.NextValue() / 1024 / 1024 / 100).ToString("0.00")}%  硬盘使用：{distinfo}";
        }
        #endregion

        #region 初始化
        public Main_method()
        {
            Init();
        }

        public void Init()
        {
            if (isLinux)
            {
                sSH = new SSHHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
                sSH.Connect();
                sFTP = new SFTPHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
            }
            else
            {
                cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                memoryCounter = new PerformanceCounter("Process", "Working Set - Private", "_Total");
                cpuCounter.NextValue();
                memoryCounter.NextValue();
                //counters = new PerformanceCounter[System.Environment.ProcessorCount];
                //for (int i = 0; i < counters.Length; i++)
                //{
                //    counters[i] = new PerformanceCounter("Processor", "% Processor Time", "_Total");
                //    counters[i].NextValue();
                //}
            }
            isInit = true;
        }
        #endregion

        #region 2.0一键安装
        public void New_Install(bool Clear_Image, string fileName = null)
        {
            var installpath = Const.config.install_item_dir;
            var flag = true;
            var tmp = installpath.Split('/');
            var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
            var ihdis_port = item.DefaultPort;
            var mask = item.DefaultMask;
            try
            {

                if (isLinux)
                {
                    #region Linux
                    //检测mask
                    Const.write_task_log("正在检测网络...");
                    var masks = CheckMask();
                    if (masks.Contains(item.DefaultPort))
                    {
                        item.DefaultMask = GetMask(masks);
                        Const.write_task_log($"网络已存在，自动生成新的mask = {item.DefaultMask}...");
                        Const.SaveMultiEnv();
                    }
                    Const.Port = ihdis_port;
                    var version = tmp[tmp.Length - 1];
                    var filepath = Const.config.localfile_path;
                    var fi = new FileInfo(filepath);
                    file_lenth = fi.Length;
                    //1，上传文件
                    Const.write_task_log("正在准备上传文件...");
                    Upload(Upload_Info);

                    //2，安装unzip，解压文件，删除旧文件,旧容器
                    Const.write_task_log("正在安装系统组件和初始化...");
                    sSH.Excute_Longcmd_NoError($"sudo rpm -ivh {Const.Script_path}/script/other/unzip-6.0-19.el7.x86_64.rpm");
                    Const.write_task_log("正在解压文件...");
                    sSH.Excute_Longcmd_NoError($"cd {installpath} ; sudo docker-compose down");
                    sSH.Excute_Longcmd_NoError($"rm -rf {installpath}");
                    sSH.Excute_Longcmd($"unzip -qo /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]} -d {installpath}");

                    //3，初始化，安装docker，docker-compose等
                    sSH.Excute_Longcmd_NoError($"sudo sh {Const.Script_path}/script/init.sh {installpath}");

                    //4.加载镜像
                    Const.write_task_log("正在加载镜像...");
                    sSH.Excute_Longcmd($"sh {installpath}/load_images.sh {installpath}");

                    //5.替换端口号
                    sSH.Excute_Longcmd($"sed -i \"s/IHDIS_PORT=.*/IHDIS_PORT={ihdis_port}/\" {installpath}/.env");
                    sSH.Excute_Longcmd($"sed -i \"s/mask=.*/mask={mask}/\" {installpath}/.env");

                    //6，创建启动容器
                    Const.write_task_log("正在创建并启动容器...");
                    sSH.Excute_Longcmd_NoError($"cd {installpath} ;sudo docker-compose up -d ");
                    Thread.Sleep(1000 * 80);

                    //7，数据库初始化
                    Const.write_task_log("数据库初始化...");
                    sSH.Excute_Longcmd_NoError($"sudo sh {Const.Script_path}/script/mysql_init.sh {installpath}");

                    //8.按照顺序重启
                    Restart_Server(installpath);
                    Thread.Sleep(1000 * 40);

                    //9，创建开机启动,数据库初始化等收尾工作
                    Const.write_task_log("正在添加开机启动...");
                    sSH.Excute_Longcmd($"sudo sh {Const.Script_path}/script/end.sh {installpath} {Const.config.ssh_user}");

                    // 10,删除多余镜像
                    if (Clear_Image)
                    {
                        Const.write_task_log("正在删除多余镜像 文件....");
                        sSH.Excute_Longcmd($"sudo docker image prune -a -f");
                        sSH.Excute_Longcmd($"sudo rm -rf  {installpath}/app/images/*");
                        sSH.Excute_Longcmd($"sudo rm -rf /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]}");
                    }
                    Const.write_task_log("正在清理缓存...");
                    sSH.Excute_Longcmd($"sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches'");

                    //11.等待webapi
                    AppInitCompleted(ihdis_port);
                    #endregion
                }
                else
                {
                    var output = string.Empty;
                    #region Windows
                    var filepath = Const.config.localfile_path;
                    var mask1 = $"172.210.{item.DefaultMask}.0";

                    //1.删除旧文件
                    Const.write_task_log("正在删除旧文件...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose down \r\nexit", out output);
                    Const.DeleteADirectory(installpath + "\\");

                    //2.解压
                    Const.write_task_log("正在解压安装包...");
                    if (!Directory.Exists(installpath))
                        Directory.CreateDirectory(installpath);
                    Const.ExtractZipFile(filepath, installpath, "", ProcessFile);

                    //copy appsettings.json
                    File.Copy($"{installpath}\\conf\\app\\webapi\\appsettings.json", $"{installpath}\\code\\webapi\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\hfs\\appsettings.json", $"{installpath}\\code\\hfs\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\rtm\\appsettings.json", $"{installpath}\\code\\rtm\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\job\\appsettings.json", $"{installpath}\\code\\job\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\iot\\appsettings.json", $"{installpath}\\code\\iot\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\ts\\appsettings.json", $"{installpath}\\code\\ts\\appsettings.json", true);

                    //3.加载镜像
                    Const.write_task_log("正在加载镜像...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\n.\\load_images.cmd\r\nexit", out _);

                    //4.替换端口号、子网掩码
                    var env = File.ReadAllText($"{installpath}/.env");
                    var newEnv = Regex.Replace(env, @"IHDIS_PORT=\d*", $"IHDIS_PORT={ihdis_port}");
                    newEnv = Regex.Replace(newEnv, @"mask=\d*", $"mask={mask}");
                    File.WriteAllText($"{installpath}/.env", newEnv);

                    var yml = File.ReadAllText($"{installpath}/docker-compose.yml");
                    yml = yml.Replace(defaultSubnet, mask1);
                    File.WriteAllText($"{installpath}/docker-compose.yml", yml);

                    //5.生成Docker Desktop挂载目录
                    AddDockerMountPath(yml, installpath);

                    //6.启动容器
                    Const.write_task_log("正在启动容器...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose up -d \r\nexit", out _);
                    Thread.Sleep(1000 * 80);

                    //7.数据库初始化
                    Const.write_task_log("正在进行数据库初始化...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost mysql --default-character-set=utf8 < conf/mysql/hdis_db.sql" +
                        $"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost hdis --default-character-set=utf8 < conf/mysql/hdis_table.sql" +
                        $"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost mysql --default-character-set=utf8 < conf/mysql/hdis_user.sql" +
                        //$"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost -e \"use mysql;update user set authentication_string = password('jlmed#123'), password_expired = 'N', password_last_changed = now() where user = 'root';flush privileges;\"" +
                        $"\r\n", out _);

                    Thread.Sleep(1000 * 40);

                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose exec -T mysql mysql -uroot -hlocalhost -e \"ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'jlmed#123'; flush privileges;\"" +
                       $"\r\n", out _);

                    Thread.Sleep(1000 * 10);

                    Const.write_task_log("正在进行重启容器...");

                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                      $"\r\ndocker-compose down" +
                       $"\r\n", out _);

                    Thread.Sleep(1000 * 10);

                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                      $"\r\ndocker-compose up -d \r\nexit", out _);
                    Thread.Sleep(1000 * 10);

                    //8.重启rtm，job，防止连接不上
                    Restart_Server(installpath);
                    Thread.Sleep(1000 * 10);

                    #endregion
                }
            }
            catch (Exception ex)
            {
                Const.write_task_log($"StackTrace:{ex.StackTrace}");
                MessageBox.Show($"安装过程出错，请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}");
                flag = false;
            }
            End_Init(flag);
        }

        private List<string> CheckMask()
        {
            List<string> lst = new List<string>();
            try
            {
                var b_suc = ExecSsh("sudo ip route", out string result);
                result
                    .Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Where(o => o.StartsWith("172."))
                    .ToList()
                    .ForEach(s =>
                    {
                        lst.Add(s.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[2]);
                    });
            }
            catch (Exception ex)
            {
                Const.write_task_log("检测子网掩码失败：" + ex);
            }
            return lst;
        }
        private string GetMask(List<string> lst)
        {
            while (true)
            {
                var r = new Random().Next(1, 255).ToString();
                if (!lst.Contains(r))
                {
                    return r.ToString();
                }
                System.Threading.Thread.Sleep(1);
            }
        }
        private bool ExecSsh(string command, out string result)
        {
            bool b_suc = false;
            result = string.Empty;
            try
            {
                using (SshClient ssh = new SshClient(Const.config.ip, 22, "root", Const.config.supasswd))
                {
                    ssh.Connect();

                    var cmd = ssh.RunCommand(command);
                    if (cmd.ExitStatus != 0)
                    {
                        result = cmd.Error;
                    }
                    else
                    {
                        b_suc = true;
                        result = $"{cmd.Result}{cmd.Error}";
                    }
                }
            }
            catch (Exception ex)
            {
                result = ex.Message;
            }
            Const.write_log(result);
            return b_suc;
        }
        #endregion

        #region 2.0 一键升级
        public void New_Update(bool Clear_Image, string comment)
        {
            var installpath = Const.config.install_item_dir;
            var flag = true;
            var tmp = installpath.Split('/');
            var item = Const.MultiEnvs.Where(o => o.Ip == Const.config.ip && o.FileName == tmp[tmp.Length - 1]).FirstOrDefault();
            var ihdis_port = item.DefaultPort;
            var mask = item.DefaultMask;
            Dictionary<string, string> recovery = new Dictionary<string, string>();
            try
            {
                var apps = comment.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                    .ToList()
                   .Where(str => str.Trim().StartsWith("Moudule: "))
                   .FirstOrDefault()
                   ?.Replace("Moudule: ", "")
                   .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                   .ToList();
                var filepath = Const.config.localfile_path;
                var recoverypath = $"/tmp/{DateTime.Now.ToString("yyyyMMddHHmmss")}";
                if (isLinux)
                {
                    Const.Port = ihdis_port;
                    var fi = new FileInfo(filepath);
                    file_lenth = fi.Length;

                    //1 上传文件
                    Const.write_task_log("正在准备上传文件...");
                    Upload(Upload_Info);

                    //2 创建备份路径
                    Const.write_task_log("正在创建备份路径...");
                    sSH.Excute_Longcmd($"sudo mkdir {recoverypath}");

                    //3 更新容器
                    Const.write_task_log("正在更新容器...");
                    apps.ForEach(m =>
                    {
                        Const.write_task_log($"正在更新模块 {m}...");
                        switch (m)
                        {
                            case "web":
                            case "pad":
                                {
                                    Const.write_task_log($"正在备份 {m}...");
                                    sSH.Excute_Longcmd($"sudo cp -r {installpath}/app/www/{m} {recoverypath}");
                                    sSH.Excute_Longcmd($"sudo rm -rf {installpath}/app/www/{m}/*");
                                    if (!recovery.ContainsKey(m))
                                        recovery.Add(m, $"sudo cp -r {recoverypath}/{m} {installpath}/app/www");
                                    break;
                                }
                            case "ts":
                            case "hfs":
                            case "job":
                            case "iot":
                            case "rtm":
                            case "webapi":
                                {
                                    Const.write_task_log($"正在备份 {m}...");
                                    sSH.Excute_Longcmd($"sudo cp -r {installpath}/code/{m} {recoverypath}");
                                    sSH.Excute_Longcmd($"sudo rm -rf {installpath}/code/{m}/*");
                                    if (!recovery.ContainsKey(m))
                                        recovery.Add(m, $"sudo cp -r {recoverypath}/{m} {installpath}/code");
                                    break;
                                }
                            case "andriod":
                                //不处理
                                break;
                            default:
                                Const.write_task_log($"模块不支持 {m}...");
                                return;
                        }
                    });
                    sSH.Excute_Longcmd($"unzip -qo /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]} -d {installpath}");
                    //4 启动容器
                    Const.write_task_log("正在重新启动容器...");
                    sSH.Excute_Longcmd_NoError($"cd {installpath} ;sudo docker-compose restart ");
                    //5 按照顺序重启
                    Restart_Server(installpath);
                    //6 清理缓存
                    if (Clear_Image)
                    {
                        Const.write_task_log("正在删除多余镜像 文件....");
                        sSH.Excute_Longcmd($"sudo docker image prune -a -f");
                        sSH.Excute_Longcmd($"sudo rm -rf  {installpath}/app/images/*");
                        sSH.Excute_Longcmd($"sudo rm -rf /home/{Const.config.ssh_user}/ihdis/{filepath.Split('\\')[filepath.Split('\\').Length - 1]}");
                    }
                    Const.write_task_log("正在清理缓存...");
                    sSH.Excute_Longcmd_NoError($"sudo rm -rf {recoverypath}");
                    sSH.Excute_Longcmd_NoError($"sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches'");
                    //6.等待webapi
                    AppInitCompleted(ihdis_port);
                }
                else
                {
                    #region Windows

                    foreach (var app in apps)
                    {
                        Const.write_task_log($"正在备份 {app}...");

                        var appPath = $"{recoverypath}\\{app}";

                        if (!Directory.Exists(appPath))
                            Directory.CreateDirectory(appPath);

                        switch (app)
                        {
                            case "web":
                            case "pad":
                                {
                                    Const.CopyDir($"{installpath}\\app\\www\\{app}", appPath);
                                    break;
                                }
                            case "hfs":
                            case "job":
                            case "rtm":
                            case "webapi":
                                {
                                    Const.CopyDir($"{installpath}\\code\\{app}", appPath);
                                    break;
                                }
                            default:
                                break;
                        }
                    }

                    //6，创建启动容器
                    Const.write_task_log("正在停止服务...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose down \r\nexit", out _);

                    //1.删除旧版前端文件
                    Const.write_task_log("正在删除旧文件...");
                    Const.DeleteADirectory(installpath + "\\app\\www");

                    //2.备份旧版本tag及nginx配置文件
                    File.Copy($"{installpath}\\.env", $"{installpath}\\.env.back", true);

                    var nginxConfig = $"{installpath}/conf/nginx/site/web.conf";
                    File.Copy(nginxConfig, $"{nginxConfig}.back", true);

                    var webapiConfig = $"{installpath}/conf/app/webapi/appsettings.json";
                    File.Copy(webapiConfig, $"{webapiConfig}.back", true);

                    var jobConfig = $"{installpath}/conf/app/job/appsettings.json";
                    File.Copy(jobConfig, $"{jobConfig}.back", true);

                    //3.解压
                    Const.write_task_log("正在解压安装包...");
                    if (!Directory.Exists(installpath))
                        Directory.CreateDirectory(installpath);

                    Const.ExtractZipFile(filepath, installpath, "", ProcessFile);

                    //copy appsettings.json
                    File.Copy($"{installpath}\\conf\\app\\webapi\\appsettings.json", $"{installpath}\\code\\webapi\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\hfs\\appsettings.json", $"{installpath}\\code\\hfs\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\rtm\\appsettings.json", $"{installpath}\\code\\rtm\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\job\\appsettings.json", $"{installpath}\\code\\job\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\iot\\appsettings.json", $"{installpath}\\code\\iot\\appsettings.json", true);
                    File.Copy($"{installpath}\\conf\\app\\ts\\appsettings.json", $"{installpath}\\code\\ts\\appsettings.json", true);

                    //4.加载镜像
                    Const.write_task_log("正在加载镜像...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\n.\\load_images.cmd\r\nexit", out _);

                    //5.替换端口号
                    var env = File.ReadAllText($"{installpath}/.env");
                    string pattern = @"IHDIS_PORT=\d*";
                    var new_env = Regex.Replace(env, pattern, $"IHDIS_PORT={ihdis_port}");
                    new_env = Regex.Replace(new_env, @"mask=\d*", $"mask={mask}");
                    File.WriteAllText($"{installpath}/.env", new_env);

                    //6.替换网段
                    CreateNework(mask, installpath);

                    //7.创建启动容器
                    Const.write_task_log("正在更新容器...");
                    CmdHelper.RunCmd($"{installpath.Split(':')[0].Trim()}: \r\ncd {$"{installpath}/"}" +
                        $"\r\ndocker-compose up -d \r\nexit", out _);

                    // 删除nginx、webapi、job配置文件
                    File.Copy($"{nginxConfig}.back", $"{nginxConfig}", true);
                    File.Delete($"{nginxConfig}.back");

                    File.Copy($"{webapiConfig}.back", $"{webapiConfig}", true);
                    File.Delete($"{webapiConfig}.back");

                    File.Copy($"{jobConfig}.back", $"{jobConfig}", true);
                    File.Delete($"{jobConfig}.back");

                    Thread.Sleep(1000 * 20);

                    Restart_Server(installpath);
                    Thread.Sleep(1000 * 10);
                    #endregion
                }
            }
            catch (Exception ex)
            {
                var log = $"升级过程出错，请截图错误信息或复制日志后联系工程师!\r\n\r\n{ex.Message}";
                Const.write_task_log(log);
                MessageBox.Show(log);
                Const.write_task_log("开始恢复数据");
                recovery.Keys.ForEach(r =>
                {
                    try
                    {
                        Const.write_task_log($"开始恢复 {r}");
                        sSH.Excute_Longcmd_NoError(recovery[r]);
                    }
                    catch { }
                });
                Const.write_task_log("数据恢复完毕");
                flag = false;
            }
            End_Init(flag);
        }
        #endregion

        #region 重启系统容器
        public void Restart_Server(string server_path)
        {
            if (isLinux)
            {
                Thread.Sleep(2000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart rtm");
                Thread.Sleep(5000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart job");
                Thread.Sleep(2000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart hfs");
                Thread.Sleep(2000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart iot");
                Thread.Sleep(2000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart ts");
                Thread.Sleep(2000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart webapi");
                Thread.Sleep(10000);
                sSH.Excute_Longcmd_NoError($"cd {server_path};sudo docker-compose restart nginx");
            }
            else
            {
                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart rtm", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart job", out _);
                Thread.Sleep(10000);

                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart hfs", out _);
                Thread.Sleep(2000);

                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart iot", out _);
                Thread.Sleep(2000);

                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart ts", out _);
                Thread.Sleep(2000);

                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart webapi", out _);
                Thread.Sleep(10000);

                CmdHelper.RunCmd($"docker-compose -f {server_path}\\docker-compose.yml restart nginx", out _);
                Thread.Sleep(10000);

                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  rtm\r\nexit", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  job\r\nexit", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  hfs\r\nexit", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  iot\r\nexit", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  ts\r\nexit", out _);
                Thread.Sleep(2000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  webapi\r\nexit", out _);
                Thread.Sleep(10000);
                CmdHelper.RunCmd($"{server_path.Split(':')[0].Trim()}: \r\ncd {$"{server_path}/"}" +
                              $"\r\ndocker-compose restart  nginx\r\nexit", out _);
                Thread.Sleep(10000);
            }
        }
        #endregion

        #region 检测是否已经初始化完成
        /// <summary>
        /// 检测webapi是否已经初始化完成
        /// </summary>
        /// <param name="ihdis_port"></param>
        private void AppInitCompleted(string ihdis_port)
        {
            Const.write_task_log("正在等待webapi初始化...");
            int count = 20;
            while (count-- > 0)
            {
                try
                {
                    var res = HttpHelper.GetHttpResult($"http://{Const.config.ip}:{ihdis_port}00/api/Assistant/HospitalRoomList");
                    if (res.Contains("\"Code\":10000,\"Message\":\"查询成功\",\"Success\":true"))
                    {
                        break;
                    }
                }
                catch
                { }
                System.Threading.Thread.Sleep(10000);
            }
        }
        #endregion

        #region 停止测试环境
        public void stop_test()
        {
            try
            {
                if (isLinux)
                    sSH.Excute_cmd($"sudo docker-compose -f /home/{Const.config.ssh_user}/ihdis/test1/docker-compose.yml stop", out _);
            }
            catch { }
        }
        #endregion

        #region 上传文件
        public void Upload(Action<ulong> flash_upload)
        {
            var tmp = Const.config.localfile_path.Split('\\');
            string filename = tmp[tmp.Length - 1];
            SFTPHelper sFTP = new SFTPHelper(Const.config.ip, Const.config.ssh_port, Const.config.ssh_user, Const.config.ssh_passwd);
            sFTP.Connect();
            sFTP.Put(Const.config.localfile_path, $"/home/{Const.config.ssh_user}/ihdis/", filename, flash_upload);
            sFTP.Disconnect();
        }
        private long file_lenth;
        public void Upload_Info(ulong curr)
        {
            double bb = Convert.ToInt32(curr / 1024 / 1024) / Convert.ToDouble(file_lenth / 1024 / 1024);
            Const.write_task_log($"正在上传文件，当前进度{(bb * 100).ToString("f2")}%...");
        }
        #endregion

        #region 刷新解压进度文件
        void ProcessFile(object sender, ScanEventArgs e)
        {
            try
            {
                Const.write_task_log($"正在解压：{Path.GetFileName(e.Name)}");
            }
            catch
            {

            }
        }
        #endregion

        #region 获取hdis系统版本
        /// <summary>
        /// 获取ihdis系统版本
        /// </summary>
        /// <returns></returns>
        public string Get_Version()
        {
            string version = "未安装";
            try
            {
                if (isLinux)
                {
                    if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/Version", out string result))
                    {
                        version = result;
                    }
                }
                else
                {
                    if (File.Exists($"{Const.config.install_item_dir}/Version"))
                    {
                        version = File.ReadAllText($"{Const.config.install_item_dir}/Version");
                    }
                }
            }
            catch { }
            return version;
        }
        /// <summary>
        /// 获取ihdis系统数据库版本
        /// </summary>
        /// <returns></returns>
        public (bool, string) Get_DbVersion()
        {
            bool suc = false;
            string version = "未安装";
            try
            {
                if (isLinux)
                {
                    if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/DbVersion", out string result))
                    {
                        suc = true;
                        version = result.Trim();
                    }
                    else
                    {
                        if (sSH.Excute_cmd($"cat {Const.config.install_item_dir}/Version", out result))
                        {
                            suc = true;
                            version = result.Trim();
                        }
                    }
                }
                else
                {
                    if (File.Exists($"{Const.config.install_item_dir}/Version"))
                    {
                        suc = true;
                        version = File.ReadAllText($"{Const.config.install_item_dir}/Version");
                        version = version.TrimEnd(new char[] { '\r', '\n' });
                    }
                }
            }
            catch { }
            return (suc, version);
        }
        #endregion

        #region 创建网段

        /// <summary>
        /// 创建一个网段
        /// </summary>
        /// <param name="paths"></param>
        /// <returns></returns>
        public void CreateNework(string subnet, string installPath)
        {
            if (isLinux)
            {
                if (subnet != defaultSubnet)
                {
                    string cmd = $"sudo sed -i \"s/{defaultSubnet}/{subnet}/g\"  {installPath}/docker-compose.yml";
                    sSH.Excute_Longcmd_NoError(cmd);
                }
            }
            else
            {
                if (subnet != defaultSubnet)
                {
                    string path = $"{installPath}\\docker-compose.yml";
                    string tem = File.ReadAllText(path);
                    tem = tem.Replace(defaultSubnet, subnet);
                    File.WriteAllText(path, tem);
                }
            }
        }

        /// <summary>
        /// 匹配网段信息
        /// </summary>
        /// <returns></returns>
        public (string code, string installPath) MatchNetwork(string installPath)
        {
            string temp = string.Empty;
            if (isLinux)
            {
                string path = $"sudo cat {Const.config.install_dir}/{installPath}/docker-compose.yml";
                sSH.Excute_cmd(path, out temp);
            }
            else
            {
                string path = $"{Const.config.install_dir}\\{installPath}\\docker-compose.yml";
                temp = File.ReadAllText(path);
            }
            string result = Regex.Match(temp, "((25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))").Value;
            return (result, installPath);
        }

        #endregion

        #region 添加挂载目录

        /// <summary>
        /// 添加挂载目录
        /// </summary>
        /// <param name="yml"></param>
        /// <param name="installPath"></param>
        public static void AddDockerMountPath(string yml, string installPath)
        {
            var sReader = new StringReader(yml);
            var deserializer = new DeserializerBuilder().Build();
            var yamlObject = deserializer.Deserialize(sReader);
            var serializer = new SerializerBuilder().JsonCompatible().Build();

            var jsonString = serializer.Serialize(yamlObject);
            dynamic dynamicObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString);
            IDictionary<string, dynamic> services = dynamicObject.services;

            // 获取volume路径集合
            var volumeList = new List<string>();
            var volumes = services.Where(o => Const.DoesPropertyExist(o.Value, "volumes")).Select(o => o.Value.volumes).ToList();
            volumes.ForEach(v =>
            {
                var objList = (List<object>)v;
                var list = objList.ConvertAll(c => { return c.ToString(); }).ToList();
                volumeList.AddRange(list);
            });

            // 添加filesharing目录
            var settingPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\Docker\\settings.json";
            var setting = File.ReadAllText(settingPath);
            var json = JObject.Parse(setting);
            if (json.ContainsKey("filesharingDirectories"))
            {
                JArray fileSharing = (JArray)json["filesharingDirectories"];
                volumeList.ForEach(volume =>
                {
                    var path = volume.Replace("\"", "").Replace("./", "").Split(':')[0];
                    var fullPath = Path.GetFullPath(Path.Combine(installPath, path));
                    fileSharing.Add(fullPath);
                });
                File.WriteAllText(settingPath, JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented));
            }
        }

        #endregion
    }
}
