namespace Dada.Supervisor;

internal static class Program
{
    private const string MutexName = "Dada.P0A.Instance";
    private const string OpenPipeName = "Dada.P0A.Open";

    [STAThread]
    private static async Task Main(string[] args)
    {
        if (args.Length > 0)
        {
            Environment.ExitCode = await OfflineCommandRouter.RunAsync(args, new WindowsCredentialStore());
            return;
        }

        using var instance = await SingleInstanceCoordinator.TryAcquireAsync(MutexName, OpenPipeName);
        if (!instance.IsPrimary) return;

        ApplicationConfiguration.Initialize();
        using var form = new SupervisorForm(LoopbackPortGuard.Check());
        SupervisorRuntime? runtime = null;
        async Task StartRuntimeAsync()
        {
            if (runtime is not null) await runtime.DisposeAsync();
            runtime = new SupervisorRuntime(new WindowsCredentialStore());
            runtime.StateChanged += state =>
            {
                if (!form.IsDisposed) form.BeginInvoke(() => form.SetState(state));
            };
            var state = await runtime.StartAsync();
            if (!form.IsDisposed) form.SetState(state);
            if (state == SupervisorState.Ready) SupervisorForm.OpenProductInSupportedBrowser();
        }
        form.Shown += async (_, _) => await StartRuntimeAsync();
        form.RestartRequested += async () => await StartRuntimeAsync();
        _ = ListenForOpenRequestAsync(instance, form);
        Application.Run(form);
        if (runtime is not null) await runtime.DisposeAsync();
    }

    private static async Task ListenForOpenRequestAsync(SingleInstanceCoordinator instance, SupervisorForm form)
    {
        while (!form.IsDisposed)
        {
            if (await instance.WaitForOpenRequestAsync(TimeSpan.FromSeconds(30)) && !form.IsDisposed)
            {
                form.BeginInvoke(form.RestoreWindow);
            }
        }
    }
}
