using Squirrel;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BodyshopPartner.Utils
{
    public static class UpdateHandler
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        public const string UpdatePath = @"http://partner.imex.online/";

        public static async Task<bool> AreUpdatesAvailable()
        {
            try
            {
                logger.Debug("Checking if updates are available.");
                using (var updateManager = new UpdateManager(UpdatePath))
                {
                    var updateInfo = await updateManager.CheckForUpdate();
                    if (updateInfo == null || !updateInfo.ReleasesToApply.Any())
                    {
                        logger.Debug("No releases to apply.");
                        return false;
                    }

                    updateInfo.ReleasesToApply.ForEach(release => logger.Debug("Release to apply " + release.Version));
                
                    return true;
                }
            }
            catch (Exception Ex)
            {
                logger.Error(Ex, "Unable to retrieve updates. ");
                return false;
            }

        }

        public static async Task ApplyUpdates(int DownloadProgress, int InstallProgress)
        {
            try
            {
                BackupSettings();
            }
            catch (Exception ex)
            {
                logger.Warn(ex, "Unable to backup settings.");
            }

            using (var updateManager = new UpdateManager(UpdatePath))
            {
                try
                {
                    var updateInfo = await updateManager.CheckForUpdate();
                    var releases = updateInfo.ReleasesToApply;
                    logger.Debug("Applying releases", releases.ToString());
                    await updateManager.DownloadReleases(releases, _ => {
                        logger.Debug("Download Release Progress " + _.ToString());
                        DownloadProgress = _; });
                    await updateManager.ApplyReleases(updateInfo, _ => {
                        logger.Debug("Install Progress " + _.ToString());
                        InstallProgress = _; });
                }
                catch (Exception Ex)
                {
                    logger.Error("Error updating Partner App. " + Ex.ToString());
                }

            }

        }

        public static void BackupSettings()
        {
            string settingsFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
            string destination = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\..\\last.config";
            logger.Trace("Backup settings from: {0} to: {1}", settingsFile, destination);
            File.Copy(settingsFile, destination, true);
        }

        /// <summary>
        /// Restore our settings backup if any.
        /// Used to persist settings across updates.
        /// </summary>
        public static void RestoreSettings()
        {
            //Restore settings after application update            
            string destFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath;
            string sourceFile = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\..\\last.config";
            // Check if we have settings that we need to restore
            if (!File.Exists(sourceFile))
            {
                // Nothing we need to do
                return;
            }
            // Create directory as needed
            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(destFile));
            }
            catch (Exception) { }

            // Copy our backup file in place 
            try
            {
                logger.Trace("Restore settings from: {0} to: {1}", sourceFile, destFile);
                File.Copy(sourceFile, destFile, true);
            }
            catch (Exception) { }

            // Delete backup files
            try
            {
                File.Delete(sourceFile);
            }
            catch (Exception) { }
        }


    }
}
