<?xml version="1.0" encoding="UTF-8"?>
<?ifndef IncludeElectron?>
<?define IncludeElectron = 0?>
<?endif?>
<?ifndef CppSourceDir?>
<?define CppSourceDir = "src\cpp"?>
<?endif?>
<?ifndef BuildDir?>
<?define BuildDir = "build"?>
<?endif?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
     xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">

  <!--
    Lemonade Server MSI Installer - WiX 5.0
    Version: @PROJECT_VERSION@ (auto-populated by CMake)
  -->

  <Package Name="Lemonade Server"
           Manufacturer="AMD"
           Version="@PROJECT_VERSION@"
           UpgradeCode="d4e5f6a7-b8c9-4d5e-a6b7-c8d9e0f1a2b3"
           Language="1033"
           Compressed="yes"
           Scope="perUser"
           InstallerVersion="500">

    <!-- Package metadata -->
    <SummaryInformation Description="Lemonade Local LLM Server"
                        Manufacturer="AMD"
                        Keywords="LLM, AI, Server, Local" />

    <!-- Custom branding images (must be defined before UI is loaded) -->
    <!-- WixUIDialogBmp = 493×312 left-side banner for welcome/finish screens -->
    <WixVariable Id="WixUIDialogBmp" Value="$(var.CppSourceDir)\installer\installer_banner_wix.bmp" />

    <!-- WixUIBannerBmp = 493×58 top banner with lemon icon (replaces red CD) -->
    <WixVariable Id="WixUIBannerBmp" Value="$(var.CppSourceDir)\installer\top_banner.bmp" />

    <!-- Icon for installer window and Add/Remove Programs -->
    <Icon Id="LemonadeIcon" SourceFile="$(var.BuildDir)\Release\resources\static\favicon.ico" />

    <!-- Set installer window icon -->
    <Property Id="ARPPRODUCTICON" Value="LemonadeIcon" />

    <!-- Also set as the main installer icon (shows in title bar and taskbar) -->
    <Property Id="SetupIcon" Value="LemonadeIcon" />

    <!-- Add/Remove Programs properties -->
    <Property Id="ARPHELPLINK" Value="https://lemonade-server.ai" />
    <Property Id="ARPURLINFOABOUT" Value="https://lemonade-server.ai" />

    <!-- Launch conditions -->
    <Launch Condition="VersionNT &gt;= 603"
            Message="This application requires Windows 8.1 or later." />

    <!-- Upgrade logic -->
    <MajorUpgrade DowngradeErrorMessage="A newer version of Lemonade Server is already installed."
                  AllowSameVersionUpgrades="yes" />

    <!-- Custom properties for command-line installation -->
    <Property Id="ADDDESKTOPSHORTCUT" Value="1" />
    <Property Id="ADDTOSTARTUP" Value="0" Secure="yes" />
    <Property Id="LAUNCHAPP" Value="0" />

    <!-- All Users install support via command line: msiexec /i lemonade.msi ALLUSERS=1 -->
    <!-- GUI only supports per-user install (no UAC needed) -->
    <Property Id="MSIINSTALLPERUSER" Value="1" Secure="yes" />

    <!-- Enable optional checkbox on ExitDialog to open the app after install -->
<?if $(var.IncludeElectron) = 1 ?>
    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Open Lemonade App" />
<?else?>
    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Open Lemonade Web App" />
<?endif?>

    <!-- Existing MSI-based C++ install location (for in-place upgrades) -->
    <!-- Check both HKCU (per-user) and HKLM (all-users) -->
    <Property Id="EXISTINGINSTALLDIR">
      <RegistrySearch Id="FindInstallDirUser"
                      Root="HKCU"
                      Key="Software\AMD\Lemonade Server"
                      Name="InstallLocation"
                      Type="raw" />
    </Property>
    <Property Id="EXISTINGINSTALLDIRMACHINE">
      <RegistrySearch Id="FindInstallDirMachine"
                      Root="HKLM"
                      Key="Software\AMD\Lemonade Server"
                      Name="InstallLocation"
                      Type="raw" />
    </Property>

    <!-- ============================================ -->
    <!-- Conflict Detection: Block dual per-user/all-users installs -->
    <!-- ============================================ -->

    <!-- Block all-users install if per-user already exists -->
    <Launch Condition="NOT (ALLUSERS = 1 AND EXISTINGINSTALLDIR)"
            Message="Lemonade Server is already installed for the current user at [EXISTINGINSTALLDIR].&#13;&#10;&#13;&#10;Please uninstall the per-user version first before installing for all users." />

    <!-- Block per-user install if all-users already exists -->
    <Launch Condition="NOT (ALLUSERS &lt;&gt; 1 AND EXISTINGINSTALLDIRMACHINE)"
            Message="Lemonade Server is already installed for all users at [EXISTINGINSTALLDIRMACHINE].&#13;&#10;&#13;&#10;Please use the existing installation or uninstall the all-users version first." />

    <!-- Media -->
    <Media Id="1" Cabinet="lemonade.cab" EmbedCab="yes" />

    <!-- ============================================ -->
    <!-- Directory Structure -->
    <!-- ============================================ -->

    <!-- Per-User install location (default): %LOCALAPPDATA%\lemonade_server\ -->
    <StandardDirectory Id="LocalAppDataFolder">
      <Directory Id="UserInstallDir" Name="lemonade_server" />
    </StandardDirectory>

    <!-- Per-Machine install location (all users): %PROGRAMFILES%\Lemonade Server\ -->
    <StandardDirectory Id="ProgramFilesFolder">
      <Directory Id="MachineInstallDir" Name="Lemonade Server" />
    </StandardDirectory>

    <!-- Main install directory - will be redirected based on install scope -->
    <StandardDirectory Id="LocalAppDataFolder">
      <Directory Id="INSTALLDIR" Name="lemonade_server">
        <Directory Id="BinDir" Name="bin">
          <Directory Id="ResourcesDir" Name="resources">
            <Directory Id="StaticDir" Name="static" />
            <Directory Id="WebAppDir" Name="web-app" />
          </Directory>
        </Directory>
<?if $(var.IncludeElectron) = 1 ?>
        <Directory Id="ElectronAppDir" Name="app" />
<?endif?>
      </Directory>
    </StandardDirectory>

    <StandardDirectory Id="ProgramMenuFolder">
      <Directory Id="ProgramMenuDir" Name="Lemonade Server" />
    </StandardDirectory>

    <StandardDirectory Id="DesktopFolder" />
    <StandardDirectory Id="StartupFolder" />

    <!-- ============================================ -->
    <!-- Components -->
    <!-- ============================================ -->

    <!-- Executable files -->
    <ComponentGroup Id="ExecutableComponents" Directory="BinDir">
      <Component Id="LemonadeApp" Guid="c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f">
        <File Id="LemonadeServer.exe" Source="$(var.BuildDir)\Release\LemonadeServer.exe" KeyPath="yes" />
      </Component>

      <Component Id="LemonadeServer" Guid="d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a">
        <File Id="lemonade_server.exe" Source="$(var.BuildDir)\Release\lemonade-server.exe" KeyPath="yes" />
      </Component>

      <!-- lemond.exe is not installed on Windows; LemonadeServer.exe embeds the server -->

      <Component Id="LemonadeCli" Guid="12ffa6b7-831b-4d56-889c-3e7f43c8d134">
        <File Id="lemonade.exe" Source="$(var.BuildDir)\Release\lemonade.exe" KeyPath="yes" />
      </Component>

      <!-- Clean up stale lemonade:// protocol handler keys on every install.
           Handles: previous full install replaced by minimal, or Electron runtime registration.
           In full installs, LemonadeProtocolHandler recreates the keys afterward
           (WiX runs RemoveRegistryValues before WriteRegistryValues). -->
      <Component Id="CleanupProtocolHandler" Guid="f2a3b4c5-d6e7-4f8a-9b0c-1d2e3f4a5b6c">
        <RemoveRegistryKey Root="HKCU" Key="Software\Classes\lemonade" Action="removeOnInstall" />
        <RegistryValue Root="HKCU" Key="Software\AMD\Lemonade Server" Name="ProtocolCleanup" Type="integer" Value="1" KeyPath="yes" />
      </Component>

<?if $(var.IncludeElectron) = 1 ?>
      <!-- Launcher script for Lemonade Desktop App (adds lemonade-app to PATH) -->
      <Component Id="LemonadeAppLauncher" Guid="a9b0c1d2-e3f4-5a6b-7c8d-9e0f1a2b3c4d">
        <File Id="lemonade_app.cmd" Source="$(var.CppSourceDir)\installer\lemonade-app.cmd" KeyPath="yes" />
      </Component>

      <!-- Register lemonade:// URL protocol handler → Electron app -->
      <Component Id="LemonadeProtocolHandler" Guid="e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b">
        <RegistryKey Root="HKCU" Key="Software\Classes\lemonade">
          <RegistryValue Type="string" Value="URL:Lemonade Protocol" />
          <RegistryValue Type="string" Name="URL Protocol" Value="" />
        </RegistryKey>
        <RegistryKey Root="HKCU" Key="Software\Classes\lemonade\shell\open\command">
          <RegistryValue Type="string" Value="&quot;[INSTALLDIR]app\lemonade-app.exe&quot; &quot;%1&quot;" KeyPath="yes" />
        </RegistryKey>
      </Component>
<?endif?>
    </ComponentGroup>

    <!-- Resource files -->
    <ComponentGroup Id="ResourceComponents">
      <Component Id="ServerModelsJson" Directory="ResourcesDir" Guid="a8b9c0d1-e2f3-4a4b-5c6d-7e8f9a0b1c2d">
        <File Id="server_models.json" Source="$(var.BuildDir)\Release\resources\server_models.json" KeyPath="yes" />
      </Component>

      <Component Id="BackendVersionsJson" Directory="ResourcesDir" Guid="b9c0d1e2-f3a4-4b5c-6d7e-8f9a0b1c2d3e">
        <File Id="backend_versions.json" Source="$(var.BuildDir)\Release\resources\backend_versions.json" KeyPath="yes" />
      </Component>

      <Component Id="DefaultsJson" Directory="ResourcesDir" Guid="0b2d4f6a-7c8e-49f1-a2b3-c4d5e6f70819">
        <File Id="defaults.json" Source="$(var.BuildDir)\Release\resources\defaults.json" KeyPath="yes" />
      </Component>

      <Component Id="FaviconIco" Directory="StaticDir" Guid="c0d1e2f3-a4b5-4c6d-7e8f-9a0b1c2d3e4f">
        <File Id="favicon.ico" Source="$(var.BuildDir)\Release\resources\static\favicon.ico" KeyPath="yes" />
      </Component>

      <Component Id="IndexHtml" Directory="StaticDir" Guid="f3a4b5c6-d7e8-4f9a-0b1c-2d3e4f5a6b7c">
        <File Id="index.html" Source="$(var.BuildDir)\Release\resources\static\index.html" KeyPath="yes" />
      </Component>
    </ComponentGroup>

    <!-- PATH environment variable (per-user install - default) -->
    <Component Id="PathEnvironmentUser" Directory="BinDir" Guid="a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" Condition="NOT ALLUSERS OR ALLUSERS = 2">
      <Environment Id="PATHUser" Name="PATH" Value="[BinDir]" Action="set" Part="last" System="no" />
      <RegistryValue Root="HKCU" Key="Software\AMD\Lemonade Server" Name="PathSet" Type="integer" Value="1" KeyPath="yes" />
    </Component>

    <!-- PATH environment variable (all users install - via CLI ALLUSERS=1) -->
    <Component Id="PathEnvironmentMachine" Directory="BinDir" Guid="a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5e" Condition="ALLUSERS = 1">
      <Environment Id="PATHMachine" Name="PATH" Value="[BinDir]" Action="set" Part="last" System="yes" />
      <RegistryValue Root="HKLM" Key="Software\AMD\Lemonade Server" Name="PathSet" Type="integer" Value="1" KeyPath="yes" />
    </Component>

    <!-- Registry keys (per-user install - default) -->
    <Component Id="RegistryEntriesUser" Directory="INSTALLDIR" Guid="b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e" Condition="NOT ALLUSERS OR ALLUSERS = 2">
      <RegistryKey Root="HKCU" Key="Software\AMD\Lemonade Server">
        <RegistryValue Type="string" Name="InstallLocation" Value="[INSTALLDIR]" KeyPath="yes" />
        <RegistryValue Type="string" Name="Version" Value="@PROJECT_VERSION@" />
        <RegistryValue Type="integer" Name="Startup" Value="[ADDTOSTARTUP]" />
      </RegistryKey>
    </Component>

    <!-- Registry keys (all users install - via CLI ALLUSERS=1) -->
    <Component Id="RegistryEntriesMachine" Directory="INSTALLDIR" Guid="b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6f" Condition="ALLUSERS = 1">
      <RegistryKey Root="HKLM" Key="Software\AMD\Lemonade Server">
        <RegistryValue Type="string" Name="InstallLocation" Value="[INSTALLDIR]" KeyPath="yes" />
        <RegistryValue Type="string" Name="Version" Value="@PROJECT_VERSION@" />
        <RegistryValue Type="integer" Name="Startup" Value="[ADDTOSTARTUP]" />
      </RegistryKey>
    </Component>

    <!-- Start Menu shortcuts -->
    <Component Id="ProgramMenuShortcuts" Directory="ProgramMenuDir" Guid="a7b8c9d0-e1f2-4a3b-4c5d-6e7f8a9b0c1d">
      <Shortcut Id="ApplicationStartMenuShortcut"
                Name="Lemonade Server"
                Target="[BinDir]LemonadeServer.exe"
                WorkingDirectory="BinDir"
                Icon="LemonadeIcon" />
      <Shortcut Id="UninstallShortcut"
                Name="Uninstall Lemonade Server"
                Target="[SystemFolder]msiexec.exe"
                Arguments="/x [ProductCode]" />
      <RemoveFolder Id="RemoveProgramMenuDir" On="uninstall" />
      <RegistryValue Root="HKCU" Key="Software\AMD\Lemonade Server" Name="StartMenu" Type="integer" Value="1" KeyPath="yes" />
    </Component>

    <!-- Desktop shortcut (conditional) -->
    <Component Id="DesktopShortcut" Directory="DesktopFolder" Guid="c9d0e1f2-a3b4-4c5d-6e7f-8a9b0c1d2e3f" Condition="ADDDESKTOPSHORTCUT = 1">
      <Shortcut Id="DesktopShortcutId"
                Name="Lemonade Server"
                Target="[BinDir]LemonadeServer.exe"
                WorkingDirectory="BinDir"
                Icon="LemonadeIcon" />
      <RegistryValue Root="HKCU" Key="Software\AMD\Lemonade Server" Name="Desktop" Type="integer" Value="1" KeyPath="yes" />
    </Component>

    <!-- Auto-start on login: Lemonade.exe in Startup folder -->
    <Component Id="StartupShortcut" Directory="StartupFolder" Guid="d0e1f2a3-b4c5-4d6e-7f8a-9b0c1d2e3f4a">
      <Shortcut Id="StartupShortcutId"
                Name="Lemonade Server"
                Target="[BinDir]LemonadeServer.exe"
                Arguments="--silent"
                WorkingDirectory="BinDir"
                Icon="LemonadeIcon" />
      <RegistryValue Root="HKCU" Key="Software\AMD\Lemonade Server" Name="Startup" Type="integer" Value="1" KeyPath="yes" />
    </Component>

    <!-- ============================================ -->
    <!-- Features -->
    <!-- ============================================ -->

    <Feature Id="Complete" Level="1">
      <ComponentGroupRef Id="ExecutableComponents" />
      <ComponentGroupRef Id="ResourceComponents" />
<?if $(var.IncludeWebApp) = 1 ?>
      <ComponentGroupRef Id="WebAppComponents" />
<?endif?>
<?if $(var.IncludeElectron) = 1 ?>
      <ComponentGroupRef Id="ElectronAppComponents" />
<?endif?>
      <ComponentRef Id="CleanupProtocolHandler" />
      <ComponentRef Id="PathEnvironmentUser" />
      <ComponentRef Id="PathEnvironmentMachine" />
      <ComponentRef Id="RegistryEntriesUser" />
      <ComponentRef Id="RegistryEntriesMachine" />
      <ComponentRef Id="ProgramMenuShortcuts" />
      <ComponentRef Id="DesktopShortcut" />
      <ComponentRef Id="StartupShortcut" />
    </Feature>

    <!-- ============================================ -->
    <!-- UI -->
    <!-- ============================================ -->

    <!-- Simple UI: Skip license and verification screens -->
    <UI>
      <ui:WixUI Id="WixUI_InstallDir" InstallDirectory="INSTALLDIR" />

      <!-- Override: Welcome goes directly to InstallDir (skip license) -->
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="99" />

      <!-- Override: InstallDir Back goes to Welcome (skip license) -->
      <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="99" />

      <!-- Override: InstallDir Next goes straight to install (skip VerifyReady) -->
      <Publish Dialog="InstallDirDlg" Control="Next" Event="EndDialog" Value="Return" Order="98" />

      <!-- On ExitDialog, run Lemonade when user clicks Finish with checkbox checked -->
      <Publish Dialog="ExitDialog"
               Control="Finish"
               Event="DoAction"
               Value="LaunchApplication"
               Condition="WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1" />
    </UI>

    <!-- ============================================ -->
    <!-- Custom Actions -->
    <!-- ============================================ -->

    <!-- Set INSTALLDIR to per-machine location for CLI all-users install -->
    <CustomAction Id="SetInstallDirAllUsers"
                  Property="INSTALLDIR"
                  Value="[ProgramFilesFolder]Lemonade Server\" />

    <!-- Stop server before upgrade.  taskkill /t kills the entire process tree
         (LemonadeServer.exe + child processes like llama-server).  The Job Object
         in LemonadeServer.exe also guarantees children die when the parent exits. -->
    <CustomAction Id="StopServerCmd"
                  Directory="SystemFolder"
                  ExeCommand='cmd.exe /c "taskkill /f /t /im LemonadeServer.exe 2>nul &amp; taskkill /f /im lemond.exe 2>nul &amp; taskkill /f /im lemonade-server.exe 2>nul &amp; exit /b 0"'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="ignore" />

    <!-- Alias for machine-wide — same action -->
    <CustomAction Id="StopServerCmdMachine"
                  Directory="SystemFolder"
                  ExeCommand='cmd.exe /c "taskkill /f /t /im LemonadeServer.exe 2>nul &amp; taskkill /f /im lemond.exe 2>nul &amp; taskkill /f /im lemonade-server.exe 2>nul &amp; exit /b 0"'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="ignore" />

    <!-- Open the app via ExitDialog checkbox.
         Full installer: open Electron app via lemonade:// protocol.
         Minimal installer: open web app in browser. -->
<?if $(var.IncludeElectron) = 1 ?>
    <CustomAction Id="LaunchApplication"
                  Directory="SystemFolder"
                  ExeCommand='"[SystemFolder]explorer.exe" "lemonade://open"'
                  Impersonate="yes"
                  Return="asyncNoWait" />
<?else?>
    <CustomAction Id="LaunchApplication"
                  Directory="SystemFolder"
                  ExeCommand='"[SystemFolder]explorer.exe" "http://127.0.0.1:13305/"'
                  Impersonate="yes"
                  Return="asyncNoWait" />
<?endif?>

    <!-- Auto-launch LemonadeServer.exe after install completes (always runs).
         Run the exe directly — it's SUBSYSTEM:WINDOWS so no console flash. -->
    <CustomAction Id="AutoLaunchLemonade"
                  Directory="BinDir"
                  ExeCommand='[BinDir]LemonadeServer.exe'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="asyncNoWait" />

    <!-- Close Electron desktop app before install/upgrade/uninstall. -->
    <CustomAction Id="CloseElectronApp"
                  Directory="SystemFolder"
                  ExeCommand='cmd.exe /c "taskkill /f /im lemonade-app.exe 2>nul &amp; taskkill /f /im Lemonade.exe 2>nul &amp; exit /b 0"'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="ignore" />

    <!-- Stop server during uninstall — taskkill /t kills process tree. -->
    <CustomAction Id="StopServerOnUninstall"
                  Directory="SystemFolder"
                  ExeCommand='cmd.exe /c "taskkill /f /t /im LemonadeServer.exe 2>nul &amp; taskkill /f /im lemond.exe 2>nul &amp; taskkill /f /im lemonade-server.exe 2>nul &amp; exit /b 0"'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="ignore" />

    <!-- Clean up runtime-created directories during uninstall (ryzenai-server and llama folders).
         These folders are created at runtime when models are downloaded, so WiX doesn't track them. -->
    <CustomAction Id="CleanupRuntimeDirs"
                  Directory="BinDir"
                  ExeCommand='cmd.exe /c "rmdir /s /q ryzenai-server &amp; rmdir /s /q llama"'
                  Execute="immediate"
                  Impersonate="yes"
                  Return="ignore" />

    <InstallExecuteSequence>
      <!-- Set install directory to Program Files for CLI all-users install (ALLUSERS=1) -->
      <Custom Action="SetInstallDirAllUsers"
              Before="CostFinalize"
              Condition="ALLUSERS = 1" />

      <!-- Close Electron app before upgrading files -->
      <Custom Action="CloseElectronApp"
              Before="StopServerCmd" />

      <!-- Stop server from an existing MSI-based C++ install before validation (per-user) -->
      <Custom Action="StopServerCmd"
              Before="InstallValidate"
              Condition="EXISTINGINSTALLDIR AND (EXISTINGINSTALLDIR &lt;&gt; &quot;&quot;)" />

      <!-- Stop server from an existing MSI-based C++ install before validation (machine-wide) -->
      <Custom Action="StopServerCmdMachine"
              Before="InstallValidate"
              Condition="EXISTINGINSTALLDIRMACHINE AND (EXISTINGINSTALLDIRMACHINE &lt;&gt; &quot;&quot;)" />

      <!-- Stop server during uninstall before cleaning up runtime directories -->
      <Custom Action="StopServerOnUninstall"
              Before="CleanupRuntimeDirs"
              Condition="Installed AND REMOVE=&quot;ALL&quot;" />

      <!-- Clean up runtime-created directories during uninstall -->
      <Custom Action="CleanupRuntimeDirs"
              Before="RemoveFiles"
              Condition="Installed AND REMOVE=&quot;ALL&quot;" />

      <!-- Auto-launch Lemonade.exe after fresh install or upgrade -->
      <Custom Action="AutoLaunchLemonade"
              After="InstallFinalize"
              Condition="NOT Installed OR UPGRADINGPRODUCTCODE" />
    </InstallExecuteSequence>

  </Package>

</Wix>
