using System;
using Topshelf;

using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace TopshelfStudy.NetCoreDemo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var topshelfExitCode = HostFactory.Run(config =>
           {
               //使用NLog日志
               config.UseNLog(NLog.LogManager.LogFactory);

               //服务配置
               config.Service<TopshelfService>(s =>
               {
                   //定制服务(另一种:简单服务)
                   s.ConstructUsing(name => new TopshelfService());

                   //启动
                   s.WhenStarted(tc => tc.Start());
                   //停止
                   s.WhenStopped(tc => tc.Stop());

                   //暂停
                   s.WhenPaused(tc => tc.Pause());

                   //恢复
                   s.WhenContinued(tc => tc.Continue());
               });

               //运行服务帐户
               config.RunAsLocalSystem();

               //服务名(所有服务中唯一)
               config.SetServiceName("AIoT.Service.Demo");

               //服务显示名
               config.SetDisplayName("AIoT服务测试");

               //实例名:指定服务的实例名称,该名称与基本服务名称合并,并由 $分隔。
               //这是可选的,仅在指定时添加
               //此选项通常使用命令行参数设置,但在此处允许其完整性。
               config.SetInstanceName("MyService");

               //服务描述
               config.SetDescription("这是一个AIoT服务测试例子,使用Topshelf类库方便调试!");

               //服务启动模式
               config.StartAutomatically();             // 自动启动
               //config.StartAutomaticallyDelayed();    // 自动启动(延迟)
               //config.StartManually();                // 手动启动
               //config.Disabled();                     // 禁用

               //服务标识(帐号)
               //指定帐户:domain\username or username@suffix.com
               //config.RunAs("username", "password");
               //config.RunAsLocalService();
               config.RunAsLocalSystem();
               //config.RunAsNetworkService();
               //config.RunAsPrompt();
               //config.RunAsVirtualServiceAccount();

               //服务恢复
               config.EnableServiceRecovery(r =>
               {
                   //最多三个

                   //重启电脑
                   r.RestartComputer(5, "message");
                   //重启服务
                   r.RestartService(0);

                   //最后一个将处理所有后续故障
                   r.RunProgram(7, "ping baidu.com");

                   //退出码非0或者程序崩溃
                   r.OnCrashOnly();

                   //错误计数重置前的天数
                   r.SetResetPeriod(1);
               });

               //服务依赖项:可以指定服务依赖项,以便服务在从属服务启动之前不会启动。这由窗口服务控制管理器管理,而不是由顶架本身管理。
               //config.DependsOn("SomeOtherService");

               #region 高级设置
               //启用暂停并继续:指定服务支持暂停并继续,允许服务控制管理器通过暂停并继续命令到服务。
               config.EnablePauseAndContinue();

               //启用关闭:指定服务支持关闭服务命令,允许服务控制管理器快速关闭服务。
               config.EnableShutdown();

               //异常:为服务运行时引发的异常提供回调。此回调不是处理程序,不会影响 Topshelf 已经提供的默认异常处理。它旨在提供对引发异常的可见性,以便触发外部操作、日志记录等。
               config.OnException(ex =>
               {
                    // Do something with the exception
               });

               //服务恢复:要配置服务恢复选项,可以使用配置器指定一个或多个服务恢复操作。恢复选项仅在安装服务时使用,并在服务成功安装后设置。
               config.EnableServiceRecovery(rc =>
                {
                    rc.RestartService(1); // restart the service after 1 minute
                    rc.RestartComputer(1, "System is restarting!"); // restart the system after 1 minute
                    rc.RunProgram(1, "notepad.exe"); // run a program
                    rc.SetResetPeriod(1); // set the reset interval to one day
                });

               #endregion

               #region 自定义安装操作
               //这些操作允许在服务安装/卸载过程中执行用户指定的代码。每个安装操作都采用"Topshelf.HostSettings"类型的设置参数,为您提供与服务相关的属性(如实例名称、服务名称等)的 API。

               //安装操作之前
               config.BeforeInstall(settings =>
               {
               });

               //安装操作后
               config.AfterInstall(settings =>
               {

               });

               //卸载操作之前
               config.BeforeUninstall(() =>
               {

               });

               //卸载操作后
               config.AfterUninstall(() =>
               {

               });
               #endregion
           });

            //退出码
            Environment.ExitCode = (int)Convert.ChangeType(topshelfExitCode, topshelfExitCode.GetTypeCode());

            await Task.CompletedTask;
        }
    }
}