//==============================================================
//  版权所有：深圳杰文科技
//  文件名：UpgradeClient.cs
//  版本：V1.0  
//  创建者：Jay  ( QQ： 85363208 )
//  创建时间：2017-11-28 16:18
//  创建描述：
//  修改者：
//  修改时间：
//  修改说明： 
//==============================================================

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Framework.BaseUI;
using Framework.HandlerBase;
using Framework.RPC;
using Infrastructure.Components;
using Infrastructure.Utilities;

namespace Framework.MainUI
{
	public static class UpgradeClient
	{
		private const string UPGRADE_APPLICATION = "Framework.Upgrade.exe";

		public static bool Upgrade(string account, string password)
		{
			bool b = false;

			ProgressForm form = new ProgressForm();
			form.Shown += delegate
			{
				new Thread(delegate()
				{
					b = RealUpgrade(account, password);
					form.DialogResult = DialogResult.OK;
				}).Start();
			};
			form.ShowDialog();

			return b;
		}

		public static bool RealUpgrade(string account, string password)
		{
			string path = Path.Combine(System.Windows.Forms.Application.StartupPath, "Upgrade");
			if (!Directory.Exists(path)) //如果升级目录不存在，那么创建它。
			{
				Directory.CreateDirectory(path);
			}

			UpdateUpgradeExe(path);

			UpgradeConfig upgradeConfig = UpgradeConfig.Load(); //装载升级配置文件（Upgrade.config）。

			long maxVersionNo = Rpc.Create<UpgradeHandler>().GetMaxVersionNo();
			if (maxVersionNo <= upgradeConfig.VersionNo) //如果没有新版本要升级，那么返回true，通知系统继续登录。
			{
				return true;
			}

			//如果用户要升级，那么返回false，通知系统中断登录。
			DialogResult result = DialogResult.Cancel;
			while (result == DialogResult.Cancel) //为防止用户误操作，默认选择Cancel则再次提问。
			{
				result = MessageBox.Show(ClientContext.ClientUpgradeHintMsg.Fmt(upgradeConfig.VersionNo, maxVersionNo), "系统升级", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button3);
				if (result == DialogResult.No) //如果用户选择不升级，那么退出升级，继续登录。
				{
					return false;
				}
			}

			UpgradeData upgradeData = Rpc.Create<UpgradeHandler>().Upgrade(upgradeConfig.VersionNo); //调用升级服务。
			if (upgradeData.UpgradeFileList.Count == 0) //如果没有升级文件，那么返回true，通知系统继续登录。
			{
				return true;
			}

			foreach (UpgradeFile upgradeFile in upgradeData.UpgradeFileList)
			{
				string upgradeFilePath = Path.Combine(path, upgradeFile.FileName);
				string dir = Path.GetDirectoryName(upgradeFilePath);
				if (!Directory.Exists(dir))
				{
					Directory.CreateDirectory(dir);
				}
				byte[] buf = GZip.Decompress(upgradeFile.Content); //解压
				File.WriteAllBytes(upgradeFilePath, buf);
			}

			Rpc.Create<LoginHandler>().Logout(ClientContext.SessionId); //升级成功之后退出登录，以免再次自动登录提示用户已登录。

			string upgradeApplicationPath = Path.Combine(Application.StartupPath, UPGRADE_APPLICATION);
			if (!File.Exists(upgradeApplicationPath))
			{
				MsgBox.Warning("未发现升级程序，升级失败！");
				return false;
			}

			string applicationName = "";
			try
			{
				applicationName = Path.GetFileName(Application.ExecutablePath);
			}
			catch (Exception ex)
			{
				MsgBox.Warning("升级发生未知错误，无法读取应用程序名。错误原因：\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
				return false;
			}
			if (applicationName.IsNullOrEmpty() || applicationName.Trim().IsNullOrEmpty())
			{
				MsgBox.Warning("升级发生未知错误，应用程序名为空。");
				return false;
			}

			string processName = "";
			try
			{
				processName = Process.GetCurrentProcess().ProcessName;
			}
			catch (Exception ex)
			{
				MsgBox.Warning("升级发生未知错误，无法读取进程名。错误原因：\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
			}
			if (processName.IsNullOrEmpty() || processName.Trim().IsNullOrEmpty())
			{
				MsgBox.Warning("升级发生未知错误，进程名为空。");
			}

			string args = "";

			if (!ClientContext.UsbkeyAccount.IsNullOrEmpty()) //如果是U盾登录，那么不传递登录账号和密码。
			{
				args = "{0} {1} {2}".Fmt(upgradeData.VersionNo, applicationName, processName);
			}
			else
			{
				args = "{0} {1} {2} {3} {4}".Fmt(upgradeData.VersionNo, applicationName, processName, account, password);
			}

			try
			{
				Process process = Process.Start(upgradeApplicationPath, args);
				if (process == null)
				{
					MsgBox.Warning("升级程序调用错误，升级失败！");
				}
			}
			catch (Exception ex)
			{
				MsgBox.Show(ex.Message);
			}

			return false;
		}

		private static void UpdateUpgradeExe(string upgradePath)
		{
			string upgradeExePath = Path.Combine(upgradePath, UPGRADE_APPLICATION);
			if (File.Exists(upgradeExePath)) //升级器不能更新本身，因此由应用程序去更新它。
			{
				string destUpgradeExePath = Path.Combine(System.Windows.Forms.Application.StartupPath, UPGRADE_APPLICATION);
				if (File.Exists(destUpgradeExePath))
				{
					File.SetAttributes(destUpgradeExePath, FileAttributes.Normal);
					File.Delete(destUpgradeExePath);
				}
				File.Move(upgradeExePath, destUpgradeExePath);
			}
		}

	}
}
