using Microsoft.Extensions.Hosting;
using Nirvana.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace YBDevice.NApi
{
    /// <summary>
    /// 后台任务
    /// </summary>
    public class BackManagerService : BackgroundService
    {
        BackManagerOptions options = new BackManagerOptions();

        public BackManagerService(Action<BackManagerOptions> options)
        {
            options.Invoke(this.options);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            if (Configs.GetBoolValue("IsTask"))
            {
                // 延迟启动
                await Task.Delay(this.options.CheckTime, stoppingToken);

                options.OnHandler(0, $"正在启动托管服务 [{this.options.Name}]....");
                stoppingToken.Register(() =>
                {
                    options.OnHandler(1, $"托管服务  [{this.options.Name}] 已经停止");
                });

                while (!stoppingToken.IsCancellationRequested)
                {
                    try
                    {
                        options?.Callback();
                    }
                    catch (Exception ex)
                    {
                        options.OnHandler(2, $" [{this.options.Name}] 执行托管服务出错", ex);
                    }
                    await Task.Delay(this.options.CheckTime, stoppingToken);
                }
            }
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            options.OnHandler(3, $" [{this.options.Name}] 由于进程退出，正在执行清理工作");
            return base.StopAsync(cancellationToken);
        }
    }

    public class BackManagerOptions
    {
        /// <summary>
        ///  任务名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        ///  获取或者设置检查时间间隔，单位：毫秒，默认 5 秒
        /// </summary>
        public int CheckTime { get; set; } = 5 * 1000;
        /// <summary>
        ///  回调委托
        /// </summary>
        public Action Callback { get; set; }
        /// <summary>
        ///  执行细节传递委托
        /// </summary>
        public Action<BackHandler> Handler { get; set; }

        /// <summary>
        ///  传递内部信息到外部组件中，以方便处理扩展业务
        /// </summary>
        /// <param name="level">0=Info，1=Debug，2=Error,3=exit</param>
        /// <param name="message"></param>
        /// <param name="ex"></param>
        /// <param name="state"></param>
        public void OnHandler(int level, string message, Exception ex = null, object state = null)
        {
            Handler?.Invoke(new BackHandler() { Level = level, Message = message, Exception = ex, State = state });
        }
    }

    public class BackHandler
    {
        /// <summary>
        ///  0=Info，1=Debug，2=Error
        /// </summary>
        public int Level { get; set; }
        public string Message { get; set; }
        public Exception Exception { get; set; }
        public object State { get; set; }
    }
}
