using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using log4net;
using VIZ.Framework.Domain;

namespace VIZ.Framework.Module
{
    /// <summary>
    /// 应用程序启动
    /// </summary>
    public static class AppSetup
    {
        /// <summary>
        /// 日志
        /// </summary>
        private static ILog log = LogManager.GetLogger(typeof(AppSetup));

        /// <summary>
        /// 应用程序启动
        /// </summary>
        private static List<IAppSetup> appSetups = new List<IAppSetup>();

        /// <summary>
        /// 应用程序加载
        /// </summary>
        private static List<IAppSetup> appLoads = new List<IAppSetup>();

        /// <summary>
        /// 是否已经启动
        /// </summary>
        public static bool IsSetup { get; private set; }

        static AppSetup()
        {
            // 初始化应用程序启动
            InitSetup();

            // 初始化应用程序加载
            InitLoad();
        }

        /// <summary>
        /// 应用程序启动
        /// </summary>
        private static void InitSetup()
        {
            // Step 1.  应用程序安全
            appSetups.Add(new AppSetup_ApplicationSafe());

            // Step 2.  单例启动
            appSetups.Add(new AppSetup_Single());

            // Step 3.  捕获未处理异常
            appSetups.Add(new AppSetup_CatchUnhandledException());

            // Step 4.  初始化日志
            appSetups.Add(new AppSetup_LogInit());

            // Step 5.  初始化延时
            appSetups.Add(new AppSetup_DelayInit());

            // Step 6.  初始化循环
            appSetups.Add(new AppSetup_Loop());

            // Step 7.  初始化辅助类
            appSetups.Add(new AppSetup_Helper());
        }

        /// <summary>
        /// 应用程序加载
        /// </summary>
        private static void InitLoad()
        {

        }

        /// <summary>
        /// 执行
        /// </summary>
        /// <returns>应用程序启动上下文</returns>
        public static AppSetupContext Setup()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            AppSetupContext context = new AppSetupContext();

            if (IsSetup)
            {
                context.IsSuccess = false;
                context.Remarks.Add("app is already setup.");
                return context;
            }

            foreach (IAppSetup setup in appSetups)
            {
                try
                {
                    if (!setup.IsEnabled)
                        continue;

                    stopwatch.Start();
                    if (setup.Setup(context))
                    {
                        stopwatch.Stop();
                        Debug.WriteLine($"Setup || {setup.Detail} ==> {stopwatch.ElapsedMilliseconds} ms");

                        continue;
                    }

                    context.IsSuccess = false;
                    context.ProviderDetail = setup.Detail;

                    return context;
                }
                catch (Exception ex)
                {
                    log.Error(ex);

                    context.IsSuccess = false;
                    context.ProviderDetail = setup.Detail;
                    context.Exception = ex;

                    return context;
                }
            }

            context.IsSuccess = true;

            IsSetup = true;

            stopwatch.Stop();

            return context;
        }

        /// <summary>
        /// 关闭
        /// </summary>
        public static void ShutDown()
        {
            if (!IsSetup)
                return;

            try
            {
                // 发送应用程序关闭消息
                AppShutDownMessage msg = new AppShutDownMessage();
                ApplicationDomain.MessageManager.Send(msg);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }

            Stopwatch stopwatch = Stopwatch.StartNew();
            AppSetupContext context = new AppSetupContext();

            foreach (IAppSetup setup in appSetups)
            {
                try
                {
                    if (!setup.IsEnabled)
                        continue;

                    stopwatch.Start();
                    setup.Shutdown(context);
                    stopwatch.Stop();

                    Debug.WriteLine($"ShutDown || {setup.Detail} ==> {stopwatch.ElapsedMilliseconds} ms");
                }
                catch (Exception ex)
                {
                    log.Error(ex);
                }
            }

            stopwatch.Stop();

            IsSetup = false;
        }

        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="window">窗口</param>
        /// <returns>启动上下文</returns>
        public static AppSetupContext Load(Window window)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            AppSetupContext context = new AppSetupContext();
            context.Window = window;

            foreach (IAppSetup setup in appLoads)
            {
                try
                {
                    if (!setup.IsEnabled)
                        continue;

                    stopwatch.Start();
                    if (setup.Setup(context))
                    {
                        stopwatch.Stop();
                        Debug.WriteLine($"Load || {setup.Detail} ==> {stopwatch.ElapsedMilliseconds} ms");
                        continue;
                    }
                    context.IsSuccess = false;
                    context.ProviderDetail = setup.Detail;

                    return context;
                }
                catch (Exception ex)
                {
                    log.Error(ex);

                    context.IsSuccess = false;
                    context.ProviderDetail = setup.Detail;
                    context.Exception = ex;

                    return context;
                }
            }

            context.IsSuccess = true;

            stopwatch.Stop();

            return context;
        }

        /// <summary>
        /// 卸载
        /// </summary>
        public static void UnLoad()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            AppSetupContext context = new AppSetupContext();

            foreach (IAppSetup setup in appLoads)
            {
                try
                {
                    if (!setup.IsEnabled)
                        continue;

                    stopwatch.Start();
                    setup.Shutdown(context);
                    stopwatch.Stop();

                    Debug.WriteLine($"UnLoad || {setup.Detail} ==> {stopwatch.ElapsedMilliseconds} ms");
                }
                catch (Exception ex)
                {
                    log.Error(ex);
                }
            }

            stopwatch.Stop();
        }

        /// <summary>
        /// 添加启动项
        /// </summary>
        /// <param name="setup">启动项</param>
        public static void AppendSetup(IAppSetup setup)
        {
            appSetups.Add(setup);
        }

        /// <summary>
        /// 添加加载项
        /// </summary>
        /// <param name="setup">加载项</param>
        public static void AppendLoad(IAppSetup setup)
        {
            appLoads.Add(setup);
        }

        /// <summary>
        /// 获取所有的启动项
        /// </summary>
        /// <returns>启动项</returns>
        public static List<IAppSetup> GetAppSetups()
        {
            return appSetups;
        }

        /// <summary>
        /// 获取所有的加载项
        /// </summary>
        /// <returns>加载项</returns>
        public static List<IAppSetup> GetAppLoads()
        {
            return appLoads;
        }
    }
}
