# -*- mode: python; -*-

import os

Import("env")
Import("get_option")
Import("has_option")

if not env.TargetOSIs('windows'):
    Return()

import re
import subprocess
import winreg

env = env.Clone()

env.SConscript(
    dirs=[
        'ca',
    ],
    exports=[
        'env',
    ],
)

env['WIX'] = os.environ.get('WIX')
env['WIXPATH'] = r'$WIX\bin'
env['WIXHEAT'] = r'$WIXPATH\heat.exe'
env['WIXCANDLE'] = r'$WIXPATH\candle.exe'
env['WIXLIGHT'] = r'$WIXPATH\light.exe'
env['WIXUIEXT'] = r'$WIXPATH\WixUIExtension.dll'
env['WIXUTILEXT'] = r'$WIXPATH\WixUtilExtension.dll'

if not 'VCREDISTMERGEMODULEPATH' in env['MSVS']:
    print("SCons tool setup did not configure the path to the vcredist merge modules, disabling MSI installer")
    Return()

sourcesList = [ "BinaryFragment.wxs",
            "FeatureFragment.wxs",
            "LicensingFragment.wxs",
            "UIFragment.wxs",
            ]

# Need to do this in order to get scons to translate path separators into native format
buildDir = env.Dir("$BUILD_DIR").path
if has_option("use-new-tools"):
	toolBuildDir = "src\mongo-tools"
else:
	toolBuildDir = buildDir + r'\mongo'

enterprisebase = 'src\mongo\db\modules\enterprise'
enterpriseToolBuildDir = buildDir + r'\mongo\db\modules\enterprise'

# Set up parameters to pass to wix -
#
# msi_edition - "Enterprise" or "Standard"
# msi_platform - "x64" or "x86"
# msi_flavor - "2008R2Plus" or ""
#

msi_flavor = '2008R2Plus'
msi_platform = 'x64'

# Enterprise
if 'enterprise' in env['MONGO_MODULES']:
  msi_edition = 'Enterprise'
  upgrade_code = '0375833f-c12d-4faa-9a83-60730647cac3'
# Community
else:
  if get_option('ssl') == 'on':
    msi_edition = 'SSL'
    upgrade_code = '8a8f9bb3-27f7-4e47-b9a0-e52c92639e44'
  else:
    msi_edition = 'Standard'
    upgrade_code = 'ff2207b3-15d7-48d8-bceb-9551c447b4de'

sourcesList.append("Installer_64.wxs")

sources = ["wxs/" + file for file in sourcesList]
objects = ["$BUILD_DIR/msi/" + file.replace(".wxs", ".wixobj") for file in sourcesList]

full_version = env['MONGO_VERSION'].partition('-')[0]

# major version is the x.y, not the x.y.z
major_version = full_version
mv = major_version.split('.')
major_version = "%s.%s" % (mv[0], mv[1])

# We must regenerate the upgrade codes for each major release.
# i.e., 3.0, 3.2, 3.4 need new codes but not 3.2.1, 3.2.2, etc
# The build will now fail when the major version is bumped to prevent mistakes.
# When the upgrade codes are bumped, remember to raise the version number to the next major version.
# On each update to the upgrade codes:
# 1. Generate new GUIDs
# 2. Ensure each MSI gets a different GUID. This is used to identify products.
#    It allows upgrade from 3.2.0 to 3.2.1 in place instead of side-by-side.
# 3. Update the check for the next major release below so we bump the GUIDs in the future.
#
if float(major_version) > 4.2:
    # If you are troubleshooting this error, see the comment above
    env.FatalError("The upgrade codes are out of date for this release. Please \n" +
    "replace the existing GUIDs listed in this file with new GUIDs so " +
    "side-by-side installation of major versions (i.e. 3.2, and 3.4) is " +
    "supported.")

# Currently, we are planning to key the same upgrade code for each
# (msi_edition, msi_platform, msi_flavor) combination
# and change MSI ProductId on minor updates, 2.6.0 -> 2.6.1, we let Wix do automatic
# GUID generation for us rather then build a database of GUIDs in our build system
# For major updates, we are going to create a new directory/productid/upgrade_code ie, 2.6 -> 3.0


# candle: compile .wxs files into .wixobjs
env.Command(objects,
            sources,
            '"$WIXCANDLE" -wx'
            # cannot have anything other than x.x.x.x in version string.
            # we should choose a fourth version number that reflects pre-ness.
            ' -dMongoDBMajorVersion=' + major_version +
            ' -dMongoDBVersion=' + full_version +
            ' -dLicenseSource=distsrc'
            r' -dEnterpriseBase=' + enterprisebase + '\\'
            ' -dBinarySource=' + buildDir + r'\mongo'
            ' -dToolBinarySource=' + toolBuildDir +
            ' -dEnterpriseToolBinarySource=' + enterpriseToolBuildDir +
            ' -dMergeModulesBasePath=' + "\"${MSVS['VCREDISTMERGEMODULEPATH']}\"" +
            ' -dMergeModuleFileCRT=' + env.GetMergeModuleNameForFeature('CRT') +
            ' -dEdition=' + msi_edition +
            ' -d"ProductId=*\"'
            ' -dUpgradeCode=' + upgrade_code +
            ' -dCustomActionDll=' + buildDir + r'\mongo\installer\msi\ca\mongoca.dll'
            ' -dConfiguration=Release'
            ' -dOutDir=' + buildDir + r'\msi'
            ' -dPlatform=' + msi_platform +
            ' -dFlavor=' + msi_flavor +
            r' -dProjectDir=buildscripts\packaging\msi\\'
            ' -dProjectName=MongoDB'
            ' -dCompassDir=src\mongo\installer\compass'
            ' -dTargetDir=' + buildDir + r'\msi'
            ' -dTargetExt=.msi'
            ' -dTargetFileName=${SERVER_ARCHIVE}'
            r' -dSaslSource=c:\sasl\bin'
            r' -dSnmpSource=c:\snmp\bin'
            r' -dSslSource=' + env['WINDOWS_OPENSSL_BIN'] +
            ' -out ' + buildDir + r'\msi\\'
            ' -arch ' + msi_platform +
            ' -ext "$WIXUIEXT"'
            ' -ext "$WIXUTILEXT"'
            ' $SOURCES')

#light: link .objs into an msi
pre_msi = "$BUILD_DIR/msi/${SERVER_DIST_BASENAME}.pre.msi"

# Suppress VC140_CRT_CRT.MSM Internal Consistency Errors
# ICE03 - Supress "String overflow"
# -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa369037(v=vs.85).aspx
# ICE82 - Suppress "duplicate sequence number"
# -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa368798(v=vs.85).aspx
# ICE30 - Suppress "different components install same file"
# -- mongod.exe is installed in two different components but only one is ever used during an install
#    so this consistency check can be ignored.
# -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa368954(v=vs.85).aspx

pre_msi_cmd = env.Command(pre_msi,
            objects,
            '"$WIXLIGHT" -out ${TARGET} -wx -cultures:null -sice:ICE82  -sice:ICE03 -sice:ICE30'
            ' -ext "$WIXUIEXT"'
            ' -ext "$WIXUTILEXT"'
            ' ${SOURCES}')
env.NoCache(pre_msi_cmd)

# Generated Dependencies
env.Depends(pre_msi_cmd, '$BUILD_DIR/mongo/mongo.exe')
env.Depends(pre_msi_cmd, '$BUILD_DIR/mongo/mongod.exe')
env.Depends(pre_msi_cmd, '$BUILD_DIR/mongo/mongos.exe')
env.Depends(pre_msi_cmd, '$BUILD_DIR/mongo/installer/msi/ca/mongoca.dll')
env.Depends(pre_msi_cmd, '#src/mongo/installer/compass/Install-Compass.ps1')

# Source Dependencies
env.Depends(pre_msi_cmd, '#buildscripts/packaging/msi/mongod.yaml')

if 'enterprise' in env['MONGO_MODULES']:
    env.Depends(pre_msi_cmd, "#" + enterpriseToolBuildDir + "/mongodecrypt.exe")
    env.Depends(pre_msi_cmd, "#" + enterpriseToolBuildDir + "/mongoldap.exe")
    env.Depends(pre_msi_cmd, "#" + enterpriseToolBuildDir + "/mongocryptd.exe")

msi = "$BUILD_DIR/msi/${SERVER_DIST_BASENAME}.msi"
env.Command(msi,
            pre_msi,
            r'$PYTHON buildscripts\msitrim.py ${SOURCES} ${TARGET}')
env.AlwaysBuild(msi)
env.NoCache(msi)

env.Alias( "msi" , msi )
