<Project Sdk="Microsoft.NET.Sdk">

  <!--
    TeamsISO WinUI 3 host. Coexists with the WPF project (src/TeamsISO.App)
    during the redesign migration. Shares the engine (TeamsISO.Engine) and
    the NDI interop assembly via ProjectReference. Once the WinUI 3 build is
    feature-complete and tested against a real Teams meeting, the WPF
    project is retired and this becomes the only shipping host.

    Target framework choice: net8.0-windows10.0.19041.0 is the minimum the
    Windows App SDK supports cleanly. Going higher (e.g. 22621) would lock
    out Win10 1809+ operators, which is undesirable for a broadcast tool
    that still has to run on hardware in working broadcast suites.

    Packaging mode: WindowsPackageType=None for "unpackaged" — the .exe
    drops directly into Program Files via the existing MSI rather than
    going through MSIX. The Windows App Runtime install becomes a prereq
    of the MSI (or bootstrapped at startup), which matches how operators
    install NDI Runtime today.
  -->
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
    <RootNamespace>TeamsISO.App.WinUI</RootNamespace>
    <AssemblyName>TeamsISO</AssemblyName>
    <!--
      Default app.manifest deferred: WinUI 3 emits its own manifest with the
      DPI awareness + supportedOS GUIDs that match what we want. Our custom
      manifest (kept in tree at app.manifest) describes the same intent but
      doesn't currently merge cleanly with the framework-emitted manifest;
      see docs/superpowers/plans/2026-05-12-winui3-migration.md for the
      follow-up to reintroduce it via uap:VisualElements.
    -->
    <Platforms>x64;ARM64</Platforms>
    <RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
    <UseWinUI>true</UseWinUI>
    <WindowsPackageType>None</WindowsPackageType>
    <EnableMsixTooling>true</EnableMsixTooling>
    <!--
      Pinning the Windows SDK projection package: WindowsAppSDK 1.6 requires
      Microsoft.Windows.SDK.NET.Ref >= 10.0.19041.38, but the .NET 8.0.301
      SDK installed here ships an older Ref. Setting this explicitly avoids
      having to upgrade the .NET SDK on the build host.
    -->
    <WindowsSdkPackageVersion>10.0.19041.38</WindowsSdkPackageVersion>
    <!--
      Disable the XAML compiler's auto-generated Program.Main so we can write
      one that bootstraps the Windows App Runtime explicitly. The default
      generated Main calls Application.Start directly, with no Bootstrap
      initialization step — that's fine for packaged MSIX apps but blocks
      unpackaged launch on a machine where the runtime is installed only as
      a framework package. Program.cs in this project takes ownership of
      Main and calls Bootstrap.TryInitialize(0x00010006) before Start.
    -->
    <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>
    <!--
      RuntimeIdentifier locks the build to win-x64 so runtime DLLs from
      runtimes/win-x64/native (Microsoft.WindowsAppRuntime.Bootstrap.dll,
      WebView2Loader.dll) flatten into the output dir alongside the .exe.
      Without this, those DLLs sit in runtimes/win-x64/native/ and the
      loader doesn't find them at activation time.
    -->
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <!--
      Suppress the auto-injected UndockedRegFreeWinRT ModuleInitializer.
      The bundled initializer P/Invokes Microsoft.WindowsAppRuntime.dll
      during module load, BEFORE our Program.Main has a chance to call
      Bootstrap.TryInitialize. Since the runtime DLL lives in the framework
      MSIX package (not the output dir) on a framework-dependent install,
      the P/Invoke fails to locate it and the .exe dies with the generic
      "this application could not be started" dialog — diagnosed by
      following the Microsoft.WindowsAppSDK.UndockedRegFreeWinRT.CS.targets
      chain and reading the auto-init source. Our Program.cs handles the
      bootstrap explicitly in the right order.
    -->
    <WindowsAppSdkUndockedRegFreeWinRTInitialize>false</WindowsAppSdkUndockedRegFreeWinRTInitialize>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <ApplicationIcon>Assets\teamsiso.ico</ApplicationIcon>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <!--
    WindowsAppSDK 1.8 is the version whose DDLM is installed on the build
    host (verified via Get-AppxPackage MicrosoftCorporationII.WinAppRuntime.
    Main.1.8). 1.6's framework package is present, but its DDLM sibling
    isn't — bootstrap returns MDD_E_BOOTSTRAP_INITIALIZE_DDLM_NOT_FOUND.
    See docs/superpowers/work-log-2026-05-12.md for the full diagnosis.

    DataGrid lives in the older 7.x Community Toolkit because the 8.x line
    dropped it; 7.1.2 still works against WindowsAppSDK 1.8 and is the
    only currently-maintained free DataGrid for this stack.
  -->
  <ItemGroup>
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.250916003" />
    <PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" Version="7.1.2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\TeamsISO.Engine\TeamsISO.Engine.csproj" />
    <ProjectReference Include="..\TeamsISO.Engine.NdiInterop\TeamsISO.Engine.NdiInterop.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Assets\teamsiso.ico" />
    <Content Include="Assets\dragon-mark.png" />
    <Content Include="Assets\wild-dragon-wordmark.png" />
    <Content Include="Assets\Fonts\Inter.ttf" />
    <Content Include="Assets\Fonts\JetBrainsMono.ttf" />
  </ItemGroup>

  <!--
    Post-build runtimeconfig patch. .NET 8 SDK adds Microsoft.WindowsDesktop.App
    as an implicit framework reference for any -windows target framework moniker.
    WinUI 3 doesn't use that framework; including it in runtimeconfig.json
    forces the .NET host to resolve and load WindowsDesktop.App at startup,
    which contributes to the WindowsAppSDK activation chain on unpackaged
    apps. This target rewrites the generated runtimeconfig.json to drop the
    WindowsDesktop.App entry so the host loads only NETCore.App.

    The target runs after the framework-dependent build copies the
    runtimeconfig.json to the output dir, before the bin/Debug/.../win-x64/
    directory is final. It's a string-level rewrite — sufficient because the
    JSON shape is stable across SDK versions and the WindowsDesktop.App
    entry has a deterministic indent + sibling structure.
  -->
  <Target Name="StripWindowsDesktopAppFromRuntimeConfig" AfterTargets="GenerateBuildRuntimeConfigurationFiles">
    <PropertyGroup>
      <_RuntimeConfigPath>$(OutDir)$(AssemblyName).runtimeconfig.json</_RuntimeConfigPath>
    </PropertyGroup>
    <PropertyGroup Condition="Exists('$(_RuntimeConfigPath)')">
      <_RuntimeConfigContent>$([System.IO.File]::ReadAllText('$(_RuntimeConfigPath)'))</_RuntimeConfigContent>
      <_PatchedContent>$([System.Text.RegularExpressions.Regex]::Replace($(_RuntimeConfigContent), ',\s*\{\s*&quot;name&quot;:\s*&quot;Microsoft\.WindowsDesktop\.App&quot;[^\}]*\}', ''))</_PatchedContent>
    </PropertyGroup>
    <WriteLinesToFile Condition="Exists('$(_RuntimeConfigPath)') and '$(_RuntimeConfigContent)' != '$(_PatchedContent)'"
                      File="$(_RuntimeConfigPath)"
                      Lines="$(_PatchedContent)"
                      Overwrite="true"/>
    <Message Condition="Exists('$(_RuntimeConfigPath)') and '$(_RuntimeConfigContent)' != '$(_PatchedContent)'"
             Text="Stripped Microsoft.WindowsDesktop.App from $(_RuntimeConfigPath)"
             Importance="high"/>
  </Target>

</Project>
