using APCViewer.HostedService;
using APCViewer.Models;
using APCViewer.Models.Stateless.Methods;
using IFX.Shared;
using Serilog;
using System.Reflection;

namespace APCViewer;

public class Program
{

    public static int Main(string[] args)
    {
        LoggerConfiguration loggerConfiguration = new();
        Assembly assembly = Assembly.GetExecutingAssembly();
        string? assemblyName = assembly.GetName()?.Name;
        if (string.IsNullOrEmpty(assemblyName))
            throw new Exception();
        WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(new WebApplicationOptions()
        {
            Args = args,
            ContentRootPath = Path.GetDirectoryName(assembly.Location)
        });
        AppSettings appSettings = Models.Stateless.AppSettings.Get(webApplicationBuilder.Configuration);
        if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName))
            throw new Exception("Working directory name must have a value!");
        string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assemblyName, appSettings.WorkingDirectoryName);
        Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory);
        _ = ConsoleLoggerConfigurationExtensions.Console(loggerConfiguration.WriteTo);
        _ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, webApplicationBuilder.Configuration);
        _ = SerilogHostBuilderExtensions.UseSerilog(webApplicationBuilder.Host);
        Log.Logger = loggerConfiguration.CreateLogger();
        Serilog.ILogger log = Log.ForContext<Program>();
        try
        {
            IsEnvironment isEnvironment = new(webApplicationBuilder.Environment.IsDevelopment(), webApplicationBuilder.Environment.IsStaging(), webApplicationBuilder.Environment.IsProduction());
            Singleton.Background background = new(isEnvironment, appSettings, workingDirectory);
            if (isEnvironment.Development && string.IsNullOrEmpty(appSettings.URLs))
                throw new Exception();
            _ = webApplicationBuilder.Services.AddRazorPages();
            _ = webApplicationBuilder.Services.AddSingleton<AppSettings, AppSettings>(_ => appSettings);
            _ = webApplicationBuilder.Services.AddSingleton<IsEnvironment, IsEnvironment>(_ => isEnvironment);
            _ = webApplicationBuilder.Services.AddSingleton<Singleton.Background, Singleton.Background>(_ => background);
            _ = webApplicationBuilder.Services.AddHostedService(t => new TimedHostedService(isEnvironment, background));
            WebApplication webApplication = webApplicationBuilder.Build();
            if (isEnvironment.Development)
            {
                if (appSettings.URLs == "Exit")
                {
                    Environment.ExitCode = -1;
                    webApplication.Lifetime.StopApplication();
                }
            }
            else
            {
                _ = webApplication.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                _ = webApplication.UseHsts();
            }
            _ = webApplication.Lifetime.ApplicationStopped.Register(Log.CloseAndFlush);
            _ = ApplicationBuilderSerilogClientExtensions.UseSerilogIngestion(webApplication);
            _ = SerilogApplicationBuilderExtensions.UseSerilogRequestLogging(webApplication);
            _ = webApplication.UseDeveloperExceptionPage();
            _ = webApplication.UseHttpsRedirection();
            _ = webApplication.UseStaticFiles();
            _ = webApplication.UseRouting();
            _ = webApplication.MapRazorPages();
            log.Information("Starting Web Application");
            webApplication.Run();

            return 0;
        }
        catch (Exception ex)
        {
            log.Fatal(ex, "Host terminated unexpectedly");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

}