using System;
using Microsoft.Extensions.Configuration;
using Serilog;
using Topshelf;
using ZB.MOM.WW.LmxProxy.Host.Configuration;

namespace ZB.MOM.WW.LmxProxy.Host
{
    internal static class Program
    {
        static int Main(string[] args)
        {
            // 1. Build configuration (instance override file loaded from LMXPROXY_INSTANCE env var)
            var instance = Environment.GetEnvironmentVariable("LMXPROXY_INSTANCE");
            var configuration = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                .AddJsonFile($"appsettings.{instance}.json", optional: true, reloadOnChange: false)
                .AddEnvironmentVariables()
                .Build();

            // 2. Set working directory to exe location so relative log paths resolve correctly
            Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;

            // 3. Configure Serilog
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(configuration)
                .Enrich.FromLogContext()
                .Enrich.WithMachineName()
                .Enrich.WithThreadId()
                .CreateLogger();

            try
            {
                // 4. Bind configuration
                var config = new LmxProxyConfiguration();
                configuration.Bind(config);

                // 5. Configure Topshelf
                var exitCode = HostFactory.Run(host =>
                {
                    host.UseSerilog();

                    host.Service<LmxProxyService>(service =>
                    {
                        service.ConstructUsing(() => new LmxProxyService(config));
                        service.WhenStarted(s => s.Start());
                        service.WhenStopped(s => s.Stop());
                        service.WhenPaused(s => s.Pause());
                        service.WhenContinued(s => s.Continue());
                        service.WhenShutdown(s => s.Stop());
                    });

                    host.SetServiceName("ZB.MOM.WW.LmxProxy.Host");
                    host.SetDisplayName("SCADA Bridge LMX Proxy");
                    host.SetDescription("gRPC proxy for AVEVA System Platform via MXAccess COM API");

                    host.StartAutomatically();
                    host.EnablePauseAndContinue();

                    host.EnableServiceRecovery(recovery =>
                    {
                        recovery.RestartService(config.ServiceRecovery.FirstFailureDelayMinutes);
                        recovery.RestartService(config.ServiceRecovery.SecondFailureDelayMinutes);
                        recovery.RestartService(config.ServiceRecovery.SubsequentFailureDelayMinutes);
                        recovery.SetResetPeriod(config.ServiceRecovery.ResetPeriodDays);
                    });
                });

                return (int)exitCode;
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "LmxProxy service terminated unexpectedly");
                return 1;
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    }
}
