using System;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.Windows.ApplicationModel.DynamicDependency;

namespace TeamsISO.App.WinUI;

/// <summary>
/// Custom Main for the unpackaged WinUI 3 host.
///
/// The default XAML-compiler-generated Main (disabled here via the
/// DISABLE_XAML_GENERATED_MAIN compile constant) calls Application.Start
/// directly. That's fine for MSIX-packaged WinUI 3 apps where the OS
/// activates the package and the runtime is found via the package
/// dependency, but for an unpackaged .exe the Windows App Runtime has to
/// be bootstrapped explicitly before any WinUI 3 type is touched.
///
/// Bootstrap.TryInitialize(0x00010006) targets WindowsAppSDK 1.6 (the LTS
/// branch we ship against). The major nibble 0x0001 is the runtime major;
/// the minor 0x0006 is the runtime minor. If the user's machine has a
/// compatible 1.6.x framework installed (the broadcast-tool installer
/// will eventually ensure that as a prereq), Bootstrap connects and the
/// rest of the WinUI 3 surface comes alive. If not, the call returns a
/// negative HResult that we surface via Environment.Exit so the .exe
/// dies cleanly rather than throwing an opaque "this application could
/// not be started" dialog.
/// </summary>
public static class Program
{
    /// <summary>WindowsAppSDK 1.8 major/minor packed as 0x00010008.</summary>
    private const uint WindowsAppSdkMajorMinor = 0x00010008;

    [STAThread]
    public static int Main(string[] args)
    {
        if (!Bootstrap.TryInitialize(WindowsAppSdkMajorMinor, out int hr))
        {
            // The runtime isn't installed (or this build's bootstrap can't
            // find a compatible package version). Surface a Win32 error code
            // so postmortem inspection of the launch failure has more than
            // "application could not be started" to go on.
            return hr;
        }

        try
        {
            WinRT.ComWrappersSupport.InitializeComWrappers();
            Application.Start(p =>
            {
                var context = new DispatcherQueueSynchronizationContext(
                    DispatcherQueue.GetForCurrentThread());
                System.Threading.SynchronizationContext.SetSynchronizationContext(context);
                _ = new App();
            });
        }
        finally
        {
            Bootstrap.Shutdown();
        }

        return 0;
    }
}
