namespace MinicsConsole;

internal class Program
{
    private readonly static ILog _expLog = new Logger.Logger();
    public static WebApplication? WebApplication { get; private set; }

    static void Main(string[] args)
    {
        Mutex mutex = new(true, "7E862400-8020-BE75-5266-B2C4BEB54076", out bool flag);
        if (!flag)
            return;
        _expLog.Initialize("Exceptions");

        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

        if (!BaseConfigFileLoader.Load(out BasicInfo? basicInfo) || basicInfo is null)
        {
            MessageBox.Show("BaseInfo.xml Load Failed");
            return;
        }

        WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
        builder.Services.AddSignalR(
            options =>
            {
                options.EnableDetailedErrors = true;
                options.MaximumReceiveMessageSize = 524288;//256k
                
                //options.ClientTimeoutInterval = TimeSpan.FromSeconds(5);
                //options.KeepAliveInterval = TimeSpan.FromSeconds(10);
                //options.MaximumParallelInvocationsPerClient = 5;
            });
        //Host Service
        builder.Services.AddHostedService<HostLifetime>();

        //Connections
        builder.Services.AddSingleton<Mini8DataDispatcher>();
        builder.Services.AddSingleton<PLCNotifier>();
        builder.Services.AddSingleton<RTNotifier>();
        builder.Services.AddSingleton<UISender>();
        builder.Services.AddSingleton<KanbanNotifier>();
        builder.Services.AddSingleton<ILog, LogSender>();
        builder.Services.AddSingleton<ITlvProvider, RTProvider_TLV>();

        //Configs
        builder.Services.AddSingleton<BasicInfo>(basicInfo);
        builder.Services.AddSingleton<Hardwares>();
        builder.Services.AddSingleton<ConfigFiles>();
        builder.Services.AddSingleton<HardWareMonitor>();
        builder.Services.AddSingleton<HardwareAddress>();
        builder.Services.AddSingleton<ConfigFileLoader>();
        builder.Services.AddSingleton<AddressFileLoader>();
        builder.Services.AddSingleton<HardwareFileLoader>();

        //Function Helpers
        builder.Services.AddSingleton<ConfigUpdater>();
        builder.Services.AddSingleton<DataBaseSwitch>();
        builder.Services.AddSingleton<DataBaseCleaner>();
        builder.Services.AddSingleton<DailyRoutinHelper>();

        //DataBase
        builder.Services.AddSingleton<OrmCollections>();
        builder.Services.AddSingleton<HardwareDBLoader>();

        //Businesses
        builder.Services.AddSingleton<UserOperator>();
        builder.Services.AddSingleton<DatabaseOperator>();
        builder.Services.AddSingleton<HardwareOperator>();
        builder.Services.AddSingleton<ConfigFileOperator>();

        WebApplication = builder.Build();
        WebApplication.MapHub<UIHub>("/UIHub");
        WebApplication.MapHub<LogHub>("/LogHub");
        WebApplication.RunAsync($"http://{basicInfo.ServerAddress}:{basicInfo.ServerPort}").Wait();
    }


    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        string s = e.ExceptionObject!.ToString()!;
        MessageBox.Show(s);
        _expLog.Fatal(s);
    }

    private static void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
    {
        try
        {
            var s = e.Exception is null ? "Unknow" : e.Exception.ToString();
            _expLog.Error(s);
        }
        catch
        {

        }
    }
}