<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

  <!-- This is how we include wxi files -->
  <?include "parameters.wxi" ?>

  <!--
    Id="*" is to enable upgrading. * means that the product ID will be autogenerated on each build.
    Name is made of localized product name and version number.
  -->
  <Product Id="*" Name="!(loc.ProductName) v$(var.DisplayVersionNumber)" Language="!(loc.LANG)"
    Version="$(var.VersionNumber)" Manufacturer="!(loc.ManufacturerName)" UpgradeCode="$(var.UpgradeCode)">
    <Package InstallerVersion="200" InstallPrivileges="elevated"
      Compressed="yes" InstallScope="perMachine" />

    <Media Id="1" Cabinet="CincWorkstation.cab" EmbedCab="yes" CompressionLevel="high" />

    <!--
    Take advantage of Windows Installer 5.0 feature (if available) to disable
    checkpointing and other costings that take significant amounts of time
    ref: https://msdn.microsoft.com/en-us/library/windows/desktop/dd408005(v=vs.85).aspx
    -->
    <Property Id="MSIFASTINSTALL" Value="7" />

    <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />

    <!--
      If fastmsi is set, custom actions will be invoked during install to unzip
      project files, and during uninstall to remove the project folder
    -->
    <% if fastmsi %>
    <SetProperty Id="FastUnzip"
      Value="FASTZIPDIR=[INSTALLLOCATION];FASTZIPAPPNAME=cinc-workstation"
      Sequence="execute"
      Before="FastUnzip" />

    <CustomAction Id="FastUnzip"
      BinaryKey="CustomActionFastMsiDLL"
      DllEntry="FastUnzip"
      Execute="deferred"
      Impersonate="no"
      Return="check" />

    <Binary Id="CustomActionFastMsiDLL"
      SourceFile="CustomActionFastMsi.CA.dll" />

    <CustomAction Id="LaunchApplication"
        BinaryKey="WixCA"
        DllEntry="WixShellExec"
        Impersonate="yes" />

    <CustomAction Id="TaskKill"
      BinaryKey="WixCA"
      DllEntry="WixQuietExec"
      Execute="immediate"
      Return="ignore" />

    <CustomAction Id="Cleanup"
      Directory="INSTALLLOCATION"
      ExeCommand="cmd /C &quot;rd /S /Q cinc-workstation&quot;"
      Execute="deferred"
      Impersonate="no"
      Return="ignore" />

    <CustomAction Id="ClearApiServerCmd"
      Property="ClearApiServerCommandLine"
      Execute="immediate"
      Value='"[WindowsFolder]System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInteractive -InputFormat None -NoProfile -windowstyle hidden -File "Resources\assets\stopserver.ps1"' />
    <CustomAction Id="ClearApiServerCommandLine"
      BinaryKey="WixCA"
      DllEntry="WixQuietExec"
      Execute="deferred"
      Return="ignore"
      Impersonate="no" />

    <!-- Detect if ChefDK is installed - this upgrade GUID is specified in
         chef-dk/omnibus/projects/chef-dk.rb. We don't look for a specific version -
         we are incompatible with *any* DK version

         This element will set the property CHEFDK_PRESENT, We use the CHEFDK_PRESENT property in
         the installer UI, to determine whether or not to show the notification that ChefDK is
         being replaced with Workstation.

         With OnlyDetect set to 'no', it will also uninstall ChefDK as part of the actionns performed
         during CW installation.
      -->
    <Upgrade Id="AB1D6FBD-F9DC-4395-BDAD-26C4541168E7">
      <UpgradeVersion OnlyDetect="no" Minimum="0.0.0" IncludeMinimum="yes" Property="CHEFDK_PRESENT"/>
    </Upgrade>

    <InstallExecuteSequence>
      <Custom Action="TaskKill" After="InstallInitialize">1</Custom>
      <Custom Action="FastUnzip" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
      <Custom Action="ClearApiServerCmd" After="CostFinalize">REMOVE~="ALL"</Custom>
      <Custom Action="ClearApiServerCommandLine" Before="RemoveFiles">REMOVE~="ALL"</Custom>
      <Custom Action="Cleanup" After="RemoveFiles">REMOVE~="ALL"</Custom>
    </InstallExecuteSequence>

    <UI>
      <ProgressText Action="FastUnzip">!(loc.FileExtractionProgress)</ProgressText>
    </UI>
    <% end %>
    <!-- TODO
       For now, using COMMON_ALTSTARTUP which is the global auto-start folder. Note that this
       may cause some trouble - we haven't yet looked into how the App should behave when multiple
       instances are running across different users.
  -->
  <PropertyRef Id="WIX_DIR_COMMON_ALTSTARTUP" />

  <CustomActionRef Id="WixBroadcastSettingChange" />
  <CustomActionRef Id="WixBroadcastEnvironmentChange" />

  <SetDirectory Id="WINDOWSVOLUME" Value="[WindowsVolume]"/>
  <Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="WINDOWSVOLUME">
      <Directory Id="INSTALLLOCATION" Name="cinc-project">
        <Directory Id="PROJECTLOCATION" Name="cinc-workstation">
          <Directory Id="PROJECTLOCATIONBIN" Name="bin">
            <Component Id="ChefWSPath" Guid="{BC744260-FD5B-4A0F-8EE5-76283072CC09}" >
              <Environment Id="Environment"
                Name="PATH" Action="set" Part="last" System="yes" Value="[PROJECTLOCATIONBIN]" />
            </Component>
            <Component Id="ChefWSRegistryEntries" Guid="{67E30C25-5311-4584-9A17-5D47AC28F9CD}">
              <RegistryKey Root="HKLM" Key="Software\Cinc\Cinc Workstation">
                <RegistryValue Type="string" Name="InstallDir" Value="[PROJECTLOCATION]" />
                <RegistryValue Type="string" Name="BinDir" Value="[PROJECTLOCATIONBIN]" />
              </RegistryKey>
            </Component>
            <Component Id="StartChefWSPowershellScript" Guid="{69EF5736-ED67-45B3-887A-FBFC0AB6DA13}" >
              <!-- Note that this refers to a Source relative to the package build directory,
                     and not in the zip file which contains all of the chef-workstation build -->
                <File Id="StartChefWSScript" Source="Resources\assets\start-chefws.ps1" KeyPath="yes" />
              </Component>
            </Directory>
            <Directory Id="PSMODULES" Name="modules" >
              <Component Id="ChefPSModulePath" Guid="{FA4B6948-087F-4460-A741-47E5A5E3B235}" >
                <Environment Id="ChefPSModulePathEnvironment"
                  Name="PSModulePath" Action="set" Part="last" System="yes" Value="[PSMODULES]" />
              </Component>
              <Component Id="ChefPowerShellRegistryEntries" Guid="{CA712E00-B031-424D-A439-838454AF94C5}">
                <RegistryKey Root="HKCR" Key="Chef.PowerShell">
                  <RegistryValue Type="string" Value="Chef.PowerShell" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="Chef.PowerShell\CLSID">
                  <RegistryValue Type="string" Value="{9008CA83-83E4-41FF-9C07-696E2CC47B52}" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}">
                  <RegistryValue Type="string" Value="Chef.PowerShell" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32">
                  <RegistryValue Type="string" Value="[System64Folder]mscoree.dll" />
                  <RegistryValue Type="string" Name="ThreadingModel" Value="Both" />
                  <RegistryValue Type="string" Name="Class" Value="Chef.PowerShell" />
                  <RegistryValue Type="string" Name="Assembly" Value="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" />
                  <RegistryValue Type="string" Name="RuntimeVersion" Value="v4.0.30319" />
                  <RegistryValue Type="string" Name="CodeBase" Value="[PSMODULES]chef\Chef.PowerShell.dll" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\InprocServer32\1.0.0.0">
                  <RegistryValue Type="string" Name="Class" Value="Chef.PowerShell" />
                  <RegistryValue Type="string" Name="Assembly" Value="Chef.PowerShell, Version=1.0.14.0, Culture=neutral, PublicKeyToken=7def9f799d039a95" />
                  <RegistryValue Type="string" Name="RuntimeVersion" Value="v4.0.30319" />
                  <RegistryValue Type="string" Name="CodeBase" Value="[PSMODULES]chef\Chef.PowerShell.dll" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\ProgId">
                  <RegistryValue Type="string" Value="Chef.PowerShell" />
                </RegistryKey>
                <RegistryKey Root="HKCR" Key="CLSID\{9008CA83-83E4-41FF-9C07-696E2CC47B52}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}" />
              </Component>
            </Directory>
            <Directory Id="EMBEDDED" Name="embedded" >
              <Directory Id="EMBEDDEDBIN" Name="bin" >
                <Component Id="ChefWSEnvHacks" Guid="{3498A65D-33D8-4CF2-BAB8-6FA072A7070D}" >
                  <Environment Id="EnvHacksEnvironment"
                    Name="CHEFWS_ENV_FIX" Action="set" System="yes" Value="1" />
                </Component>
              </Directory>
            </Directory>
          </Directory>
        </Directory>
      </Directory>
      <Directory Id="ProgramMenuFolder">
        <!-- Place shortcuts grouped in a "Cinc Workstation" folder in the Start menu -->
        <Directory Id="CincWorkstationFolder" Name="Cinc Workstation">
          <Component Id="PowershellStartMenuShortcut" Guid="{6DD3FFF3-E009-40E7-B1C2-EF606B941CCD}">
            <Shortcut Id="PowershellStartMenuShortcutDef"
              Name="!(loc.ChefWSPowershellShortcutDefName)"
              Description="!(loc.ChefWSPowershellShortcutDefDesc)"
              Target="[WindowsFolder]\System32\WindowsPowerShell\v1.0\powershell.exe"
              Arguments="-NoProfile -ExecutionPolicy Bypass -File [#StartChefWSScript]"
              Show="minimized"
              Icon="cwsps.ico"/>
          </Component>
        </Directory>
      </Directory>

      <Directory Id="DesktopFolder" Name="Desktop">
        <Component Id="PowershellDesktopShortcut" Guid="{396E22A6-A7B6-4AA1-B63C-83A3DD7007A8}">
          <Shortcut Id="PowershellDesktopShortcutDef"
            Name="!(loc.ChefWSPowershellShortcutDefName)"
            Description="!(loc.ChefWSPowershellShortcutDefDesc)"
            Target="[WindowsFolder]\System32\WindowsPowerShell\v1.0\powershell.exe"
            Arguments="-NoProfile -ExecutionPolicy Bypass -File [#StartChefWSScript]"
            Show="minimized"
            Icon="cwsps.ico"/>
        </Component>
      </Directory>
    </Directory>

    <!-- Set the components defined in our fragment files that will be used for our feature  -->
    <!-- Renders the following install options
         [x] Cinc Workstation
           [x] Start Menu Shortcut
           [x] Desktop Shortcut
           [ ] Environment Customizations
    -->
    <Feature Id="ChefWSFeature" Title="!(loc.FeatureMainName)"
      Description="!(loc.FeatureMainDesc)"
      Absent="disallow" AllowAdvertise="no" Level="1" ConfigurableDirectory="INSTALLLOCATION">
      <ComponentGroupRef Id="ProjectDir" />
      <ComponentRef Id="ChefWSPath" />
      <ComponentRef Id="ChefPSModulePath" />
      <ComponentRef Id="ChefPowerShellRegistryEntries" />
      <ComponentRef Id="ChefWSRegistryEntries" />
      <Feature Id="ChefWSStartMenuPSShortcutFeature" Title="!(loc.FeatureChefWSStartMenuPSShortcut)"
        Description="!(loc.FeatureChefWSStartMenuPSShortcutDesc)" Level="1" AllowAdvertise="no" >
        <ComponentRef Id="StartChefWSPowershellScript" />
        <ComponentRef Id="PowershellStartMenuShortcut" />
      </Feature>
      <Feature Id="ChefWSDesktopPSShortcutFeature" Title="!(loc.FeatureChefWSDesktopPSShortcut)"
        Description="!(loc.FeatureChefWSDesktopPSShortcutDesc)" Level="1" AllowAdvertise="no" >
        <ComponentRef Id="StartChefWSPowershellScript" />
        <ComponentRef Id="PowershellDesktopShortcut" />
      </Feature>
      <Feature Id="ChefWSEnvHacks" Title="!(loc.FeatureChefWSEnvHacks)" Description="!(loc.FeatureChefWSEnvHacksDesc)" Level="1000" AllowAdvertise="no">
        <ComponentRef Id="ChefWSEnvHacks" />
      </Feature>
    </Feature>

    <!--
    UI Stuff
    -->
    <Icon Id="cws16.ico" SourceFile="Resources\assets\cws_16x16.ico"/>
    <Icon Id="cws32.ico" SourceFile="Resources\assets\cws_32x32.ico"/>
    <Icon Id="cws.ico" SourceFile="Resources\assets\cws.ico"/>
    <Icon Id="cwsps.ico" SourceFile="Resources\assets\cwsps.ico"/>
    <Property Id="ARPPRODUCTICON" Value="cws16.ico" />
    <Property Id="ARPHELPLINK" Value="https://cinc.sh/" />
    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
    <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>

    <!-- Use our custom UI sequence which is based on WixUI_FeatureTree  - the default WIX installer UI that includes a feature tree
         The fragment containing ChefWS_FeatureTree is at the bottom of this file;  omnibus does not currently support
         compiling multiple wix source files, so we can't move it to its own file -->
    <UIRef Id="ChefWS_FeatureTree"/>

    <WixVariable Id="WixUILicenseRtf" Value="Resources\assets\LICENSE.rtf" />
    <WixVariable Id="WixUIDialogBmp" Value="Resources\assets\dialog_background.bmp" />
    <WixVariable Id="WixUIBannerBmp" Value="Resources\assets\banner_background.bmp" />
    <WixVariable Id="WixUINewIco" Value="Resources\assets\cws_16x16.ico" />
    <WixVariable Id="WixUIUpIco" Value="Resources\assets\cws_16x16.ico" />

  </Product>

    <!-- We copied this fragment in fromn WixUI_FeatureTree, based on the instructions here:
         http://wixtoolset.org/documentation/manual/v3/wixui/wixui_customizations.html#inserting-a-custom-dialog-into-a-built-in-dialog-set

         It's modified to inject the ChefDK warning (if DK is present) prior to the VerifyReadyDlg -->
    <!--
    First-time install dialog sequence:
     - WixUI_WelcomeDlg
     - WixUI_LicenseAgreementDlg
     - WixUI_CustomizeDlg
     - DlgDKInstalled (if installed)
     - WixUI_VerifyReadyDlg
     - WixUI_DiskCostDlg
    Maintenance dialog sequence:
     - WixUI_MaintenanceWelcomeDlg
     - WixUI_MaintenanceTypeDlg
     - WixUI_CustomizeDlg
     - DlgDKInstalled (if installed)
     - WixUI_VerifyReadyDlg
    Patch dialog sequence:
     - WixUI_WelcomeDlg
     - WixUI_VerifyReadyDlg
    -->
  <Fragment>
    <UI Id="ChefWS_FeatureTree">
      <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
      <TextStyle Id="WixUI_Font_Normal_White" FaceName="Tahoma" Size="8"  Red="255" Green="255" Blue="255" />
      <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
      <TextStyle Id="WixUI_Font_Bigger_White" FaceName="Tahoma" Size="12" Red="255" Green="255" Blue="255" />
      <TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
      <TextStyle Id="WixUI_Font_Title_White" FaceName="Tahoma" Size="9" Bold="yes" Red="255" Green="255" Blue="255" />

      <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
      <Property Id="WixUI_Mode" Value="FeatureTree" />

      <DialogRef Id="ErrorDlg" />
      <DialogRef Id="FatalError" />
      <DialogRef Id="FilesInUse" />
      <DialogRef Id="MsiRMFilesInUse" />
      <DialogRef Id="PrepareDlg" />
      <DialogRef Id="ProgressDlg" />
      <DialogRef Id="ResumeDlg" />
      <DialogRef Id="UserExit" />
      <DialogRef Id="DlgDKInstalled" />

      <Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
      <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return">1</Publish>

      <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

      <!-- WelcomeDlg buttons -->
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">
        <![CDATA[NOT Installed]]>
      </Publish>
      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="DlgDKInstalled">
        <![CDATA[CHEFDK_PRESENT AND Installed AND PATCH]]>
      </Publish>

      <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">
        <![CDATA[Installed AND PATCH]]>
      </Publish>

      <!-- MaintenanceTypeDlg buttons -->
      <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
      <Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="CustomizeDlg">1</Publish>
      <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
      <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>

      <!-- LicenseAgreementDlg: buttons -->
      <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
      <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="CustomizeDlg">
        <![CDATA[LicenseAccepted = "1"]]>
      </Publish>

      <!-- CustomizeDlg: Back button  - only one will fire due to conditionals-->
      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">Installed</Publish>
      <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg" Order="2">
        <![CDATA[NOT Installed]]>
      </Publish>

      <!-- CustomizeDlg: Next button -->
      <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="DlgDKInstalled" Order="3">CHEFDK_PRESENT</Publish>
      <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>


      <!-- DlgDKInstalled: Back button -->
      <Publish Dialog="DlgDKInstalled" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="1">
        <![CDATA[Installed AND PATCH]]>
      </Publish>
      <Publish Dialog="DlgDKInstalled" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="2">
        <![CDATA[NOT Installed OR WixUI_InstallMode = "Change"]]>
      </Publish>
      <Publish Dialog="DlgDKInstalled" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="3">
        <![CDATA[Installed AND NOT PATCH]]>
      </Publish>

      <Publish Dialog="DlgDKInstalled" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="DlgDKInstalled">
        <![CDATA[CHEFDK_PRESENT AND (NOT Installed OR WixUI_InstallMode = "Change")]]>
      </Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="2">
        <![CDATA[NOT CHEFDK_PRESENT AND (NOT Installed OR WixUI_InstallMode = "Change")]]>
      </Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="3">
        <![CDATA[Installed AND NOT PATCH]]>
      </Publish>
      <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="4">
        <![CDATA[Installed AND PATCH]]>
      </Publish>
    </UI>
    <UI>
      <!-- Our custom dialog to show that DK is installed/will be removed. -->
      <Dialog Id="DlgDKInstalled" Width="370" Height="270" Title="!(loc.DlgDKInstalled_Title)">
        <Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.DlgDKInstalled_BannerBitmap)" />
        <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
        <Control Id="BannerText" Type="Text" X="15" Y="15" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.DlgDKInstalled_BannerText)" />
        <Control Id="Message" Type="Text" X="25" Y="55" Width="320" Height="20" Transparent="yes" NoPrefix="yes" Text="!(loc.DlgDKInstalled_Message)" />

        <!-- Standard controls -->
        <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
        <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="no" TabSkip="yes" Text="!(loc.WixUIBack)" />
        <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Disabled="no" TabSkip="yes" Text="!(loc.WixUINext)" />
        <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUICancel)">
          <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
        </Control>
      </Dialog>
    </UI>
    <UIRef Id="WixUI_Common" />
  </Fragment>
</Wix>
