<#
    .SYNOPSIS
    Script to bootstrap a Haskell environment

    .DESCRIPTION
    This is the windows GHCup installer, installing:

    * ghcup - The Haskell toolchain installer"
    * ghc   - The Glasgow Haskell Compiler"
    * msys2 - Unix-style toolchain needed for dependencies and tools
    * cabal - The Cabal build tool for managing Haskell software"
    * stack - (optional) A cross-platform program for developing Haskell projects"
    * hls   - (optional) A language server for developers to integrate with their editor/IDE"
#>
param (
    # Run an interactive installation
    [switch]$Interactive,
    # Specify the install root (default: 'C:\')
    [string]$InstallDir,
    # Instead of installing a new MSys2, use an existing installation
    [string]$ExistingMsys2Dir,
    # Specify the cabal root directory (default: '$InstallDir\cabal')
    [string]$CabalDir,
    # Overwrite (or rather backup) a previous install
    [switch]$Overwrite,
    # Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell')
    [string]$BootstrapUrl,
    # Run the final bootstrap script via 'bash' instead of a full newly spawned msys2 shell
    [switch]$InBash,
    # Whether to install stack as well
    [switch]$InstallStack,
    # Whether to install hls as well
    [switch]$InstallHLS,
    # Skip adjusting cabal.config with mingw paths
    [switch]$NoAdjustCabalConfig
)

$Silent = !$Interactive

function Print-Msg {
  param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg, [string]$color = "Green" )
  Write-Host ('{0}' -f $msg) -ForegroundColor $color
}

function Create-Shortcut {
    param ( [Parameter(Mandatory=$true,HelpMessage='Target path')][string]$SourceExe, [Parameter(Mandatory=$true,HelpMessage='Arguments to the path/exe')][AllowEmptyString()]$ArgumentsToSourceExe, [Parameter(Mandatory=$true,HelpMessage='The destination of the desktop link')][string]$DestinationPath )
    $WshShell = New-Object -comObject WScript.Shell
    $Shortcut = $WshShell.CreateShortcut($DestinationPath)
    $Shortcut.TargetPath = $SourceExe
    if($ArgumentsToSourceExe) {
      $Shortcut.Arguments = $ArgumentsToSourceExe
    }
    $Shortcut.Save()
}

function Add-EnvPath {
  param(
      [Parameter(Mandatory=$true,HelpMessage='The Path to add to Users environment')]
      [string] $Path,

      [ValidateSet('Machine', 'User', 'Session')]
      [string] $Container = 'Session'
  )

  if ($Container -eq 'Session') {
      $envPaths = [Collections.Generic.List[String]]($env:Path -split ([IO.Path]::PathSeparator))
      if ($envPaths -notcontains $Path) {
          $envPaths.Add($Path)
          $env:PATH = $envPaths -join ([IO.Path]::PathSeparator)
      }
  }
  else {
      [Microsoft.Win32.RegistryHive]$hive, $keyPath = switch ($Container) {
          'Machine' { 'LocalMachine', 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' }
          'User' { 'CurrentUser', 'Environment' }
      }

      $hiveKey = $envKey = $null
      try {
          $hiveKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, '')
          $envKey = $hiveKey.OpenSubKey($keyPath, $true)
          $rawPath = $envKey.GetValue('PATH', '', 'DoNotExpandEnvironmentNames')

          $envPaths = [Collections.Generic.List[String]]($rawPath -split ([IO.Path]::PathSeparator))
          if ($envPaths -notcontains $Path) {
              $envPaths.Add($Path)
              $envKey.SetValue('PATH', ($envPaths -join ([IO.Path]::PathSeparator)), 'ExpandString')
          }
      }
      finally {
          if ($envKey) { $envKey.Close() }
          if ($hiveKey) { $hiveKey.Close() }
      }
  }
}



filter Get-FileSize {
	'{0:N2} {1}' -f $(
	if ($_ -lt 1kb) { $_, 'Bytes' }
	elseif ($_ -lt 1mb) { ($_/1kb), 'KB' }
	elseif ($_ -lt 1gb) { ($_/1mb), 'MB' }
	elseif ($_ -lt 1tb) { ($_/1gb), 'GB' }
	elseif ($_ -lt 1pb) { ($_/1tb), 'TB' }
	else { ($_/1pb), 'PB' }
	)
}

function Get-FileWCSynchronous{
    param(
        [Parameter(Mandatory=$true)]
        [string]$url, 
        [string]$destinationFolder="$env:USERPROFILE\Downloads",
        [switch]$includeStats
    )
    $wc = New-Object -TypeName Net.WebClient
    $wc.UseDefaultCredentials = $true
    $destination = Join-Path -Path $destinationFolder -ChildPath ($url | Split-Path -Leaf)
    $start = Get-Date
    $wc.DownloadFile($url, $destination)
    $elapsed = ((Get-Date) - $start).ToString('hh\:mm\:ss')
    $totalSize = (Get-Item -Path $destination).Length | Get-FileSize
    if ($includeStats.IsPresent){
        [PSCustomObject]@{Name=$MyInvocation.MyCommand;TotalSize=$totalSize;Time=$elapsed}
    }
    Get-Item -Path $destination | Unblock-File
}

function Test-AbsolutePath {
  Param (
      [Parameter(Mandatory=$True)]
      [ValidateScript({[System.IO.Path]::IsPathRooted($_)})]
      [String]$Path
  )
}

function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position = 0, Mandatory = 1)][string]$cmd,
        [Parameter()][string]$errorMessage,
        [parameter(ValueFromRemainingArguments = $true)]
        [string[]]$Passthrough
    )
    & $cmd @Passthrough
    if ($lastexitcode -ne 0) {
        if (!($errorMessage)) {
          throw ('Exec: Error executing command {0} with arguments ''{1}''' -f $cmd, "$Passthrough")
        } else {
          throw ('Exec: ' + $errorMessage)
        }
    }
}

$ErrorActionPreference = 'Stop'

$GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user')

if ($GhcupBasePrefixEnv) {
  $defaultGhcupBasePrefix = $GhcupBasePrefixEnv
} else {
  $partitions = Get-CimInstance win32_logicaldisk
  $defaultGhcupBasePrefix = $null
  foreach ($p in $partitions){
    try {
      if ($p."FreeSpace" -lt 5368709120) { # at least 5 GB are needed
        throw ("Not enough free space on {0}" -f $p."DeviceId")
      }
      $null = New-Item -Path ('{0}\' -f $p."DeviceId") -Name "ghcup.test" -ItemType "directory" -Force
      $defaultGhcupBasePrefix = ('{0}\' -f $p."DeviceId")
      Remove-Item -LiteralPath ('{0}\ghcup.test' -f $p."DeviceId")
      break
    } catch {
      Print-Msg -color Yellow -msg ("{0} not writable or not enough disk space, trying next device" -f $p."DeviceId")
    }
  }
  if ($defaultGhcupBasePrefix) {
    Print-Msg -color Green -msg ("Picked {0} as default Install prefix!" -f $defaultGhcupBasePrefix)
  } else {
    Print-Msg -color Red -msg "Couldn't find a writable partition with at least 5GB free disk space!"
    Exit 1    
  }
}

# ask for base install prefix
if ($Silent -and !($InstallDir)) {
  $GhcupBasePrefix = $defaultGhcupBasePrefix
} elseif ($InstallDir) {
  if (!(Test-Path -LiteralPath ('{0}' -f $InstallDir) -IsValid)) {
    Print-Msg -color Red -msg "Not a valid directory!"
    Exit 1
  } elseif (!(Split-Path -IsAbsolute -Path "$InstallDir")) {
    Print-Msg -color Red -msg "Non-absolute Path specified!"
    Exit 1
  } else {
    $GhcupBasePrefix = $InstallDir
  }
} else {
  while ($true) {
    Print-Msg -color Magenta -msg ('Where to install to (this should be a short Path, preferably a Drive like ''C:\''){1}Press enter to accept the default [{0}]:' -f $defaultGhcupBasePrefix, "`n")
    $basePrefixPrompt = Read-Host
    $GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt]
    if (!($GhcupBasePrefix.EndsWith('\'))) {
      $GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
    }
  
    if (!($GhcupBasePrefix)) {
      Print-Msg -color Red -msg "No directory specified!"
    } elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
      Print-Msg -color Red -msg "Directory does not exist, need to specify an existing Drive/Directory"
    } elseif (!(Split-Path -IsAbsolute -Path "$GhcupBasePrefix")) {
      Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
    } else {
      Break
    }
  }
}

Print-Msg -msg ('Setting env variable GHCUP_INSTALL_BASE_PREFIX to ''{0}''' -f $GhcupBasePrefix)
$null = [Environment]::SetEnvironmentVariable("GHCUP_INSTALL_BASE_PREFIX", $GhcupBasePrefix, [System.EnvironmentVariableTarget]::User)


$GhcupDir = ('{0}\ghcup' -f $GhcupBasePrefix)
$MsysDir = ('{0}\msys64' -f $GhcupDir)
$Bash = ('{0}\usr\bin\bash' -f $MsysDir)
if (!($BootstrapUrl)) {
  $BootstrapUrl = 'https://www.haskell.org/ghcup/sh/bootstrap-haskell'
}
$GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user')

Print-Msg -msg 'Preparing for GHCup installation...'

# ask what to do in case ghcup is already installed
if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) {
  Print-Msg -msg ('GHCup already installed at ''{0}''...' -f $GhcupDir)
  if ($Overwrite) {
    $decision = 0
  } elseif (!($Silent)) {
    $decision = $Host.UI.PromptForChoice('Install GHCup'
                                        , 'GHCup is already installed, what do you want to do?'
                                        , [System.Management.Automation.Host.ChoiceDescription[]] @('&Reinstall'
                                            '&Continue'
                                            '&Abort'), 1)
  } else {
    $decision = 1
  }

  if ($decision -eq 0) {
    $suffix = [IO.Path]::GetRandomFileName()
    Print-Msg -msg ('Backing up {0} to {0}-{1} ...' -f $GhcupDir, $suffix)
    Rename-Item -Path ('{0}' -f $GhcupDir) -NewName ('{0}-{1}' -f $GhcupDir, $suffix)
  } elseif ($decision -eq 1) {
    Print-Msg -msg 'Continuing installation...'
  } elseif ($decision -eq 2) {
    Exit 0
  }
}


$null = New-Item -Path ('{0}' -f $GhcupDir) -ItemType 'directory' -ErrorAction SilentlyContinue
$null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -ErrorAction SilentlyContinue

# ask for cabal dir destination
if ($CabalDir) {
  $CabDirEnv = $CabalDir
  if (!($CabDirEnv)) {
    Print-Msg -color Red -msg "No directory specified!"
    Exit 1        
  } elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
    Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
    Exit 1
  }
} elseif (!($Silent)) {
  while ($true) {

    $defaultCabalDir = ('{0}\cabal' -f $GhcupBasePrefix)
    Print-Msg -color Magenta -msg ('Specify Cabal directory (this is where haskell packages end up){1}Press enter to accept the default [{0}]:' -f $defaultCabalDir, "`n")
    $CabalDirPrompt = Read-Host
    $CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]

    if (!($CabDirEnv)) {
      Print-Msg -color Red -msg "No directory specified!"         
    } elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
      Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
    } else {
      Break
    }
  }
} else {
  $CabDirEnv = ('{0}\cabal' -f $GhcupBasePrefix)
}

# ask whether to install HLS
if (!($InstallHLS)) {
  if (!($Silent)) {
    $HLSdecision = $Host.UI.PromptForChoice('Install HLS'
      , 'Do you want to install the haskell-language-server (HLS) for development purposes as well?'
      , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
          '&No'
          '&Abort'), 1)

    if ($HLSdecision -eq 0) {
      $InstallHLS = $true
    } elseif ($HLSdecision -eq 2) {
      Exit 0
    }
  }
}

# ask whether to install stack
if (!($InstallStack)) {
  if (!($Silent)) {
    $StackDecision = $Host.UI.PromptForChoice('Install stack'
      , 'Do you want to install stack as well?'
      , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
          '&No'
          '&Abort'), 1)

    if ($StackDecision -eq 0) {
      $InstallStack = $true
    } elseif ($StackDecision -eq 2) {
      Exit 0
    }
  }
}


# mingw foo
Print-Msg -msg 'First checking for Msys2...'
if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
  if ($Silent) {
    $msys2Decision = 0
  } else {
    $msys2Decision = $Host.UI.PromptForChoice('Install MSys2'
        , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?'
        , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes'
            '&No'), 0)
  }

  if ($msys2Decision -eq 0) {
    Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0}' -f $MsysDir)

	Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...'
	Start-Sleep -s 5

    # Download the archive
    Print-Msg -msg 'Downloading Msys2 archive...'
    $archive = 'msys2-x86_64-latest.sfx.exe'
    
    if (Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) {
      Exec "curl.exe" '-o' ('{0}\{1}' -f $env:TEMP, $archive) ('https://repo.msys2.org/distrib/{0}' -f $archive)
    } else {
      Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder "$env:TEMP" -includeStats
    }

    Print-Msg -msg 'Extracting Msys2 archive...'
    $null = & "$env:TEMP\$archive" '-y' ('-o{0}' -f $GhcupDir)  # Extract
    Remove-Item -Path ('{0}/{1}' -f $env:TEMP, $archive)

    Print-Msg -msg 'Processing MSYS2 bash for first time use...'
    Exec "$Bash" '-lc' 'exit'

    Exec "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`"

    Print-Msg -msg 'Upgrading full system...'
    Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu'

    Print-Msg -msg 'Upgrading full system twice...'
    Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu'

    Print-Msg -msg 'Installing Dependencies...'
    Exec "$Bash" '-lc' 'pacman --noconfirm -S --needed curl mingw-w64-x86_64-pkgconf'

    Print-Msg -msg 'Updating SSL root certificate authorities...'
    Exec "$Bash" '-lc' 'pacman --noconfirm -S ca-certificates'

    Print-Msg -msg 'Setting default home directory...'
    Exec "$Bash" '-lc' "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf"
  } elseif ($msys2Decision -eq 1) {
    Print-Msg -color Yellow -msg 'Skipping MSys2 installation.'
    while ($true) {
      if ($GhcupMsys2) {
        $defaultMsys2Dir = $GhcupMsys2
        Print-Msg -color Magenta -msg ('Input existing MSys2 toolchain directory.{1}Press enter to accept the default [{0}]:' -f $defaultMsys2Dir, "`n")
        $MsysDirPrompt = Read-Host
        $MsysDir = ($defaultMsys2Dir,$MsysDirPrompt)[[bool]$MsysDirPrompt]
      } else {
        Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:' 
        $MsysDir = Read-Host
      }
      if (!($MsysDir)) {
        Print-Msg -color Red -msg "No directory specified!"         
      } elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
        Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found!' -f $MsysDir)
      } elseif (!(Split-Path -IsAbsolute -Path "$MsysDir")) {
        Print-Msg -color Red -msg "Invalid/Non-absolute Path specified"
      } else {
        Break
      }
    }
    Print-Msg -msg ('Setting GHCUP_MSYS2 env var to ''{0}''' -f $MsysDir)
    $null = [Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $MsysDir, [System.EnvironmentVariableTarget]::User)
    $Bash = ('{0}\usr\bin\bash' -f $MsysDir)
  }
} else {
    Print-Msg -msg ('...Msys2 found in {0} ...skipping Msys2 installation.' -f $MsysDir)

	Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...'
	Start-Sleep -s 5
}

Print-Msg -msg 'Creating shortcuts...'
$uninstallShortCut = @'
$decision = $Host.UI.PromptForChoice('Uninstall Haskell'
, 'Do you want to uninstall all of the haskell toolchain, including GHC, Cabal, Stack and GHCup itself?'
, [System.Management.Automation.Host.ChoiceDescription[]] @('&Uninstall'
    '&Abort'), 0)

if ($decision -eq 1) {
  Exit 0
}

Write-Host 'Removing ghcup toolchain' -ForegroundColor Green
ghcup nuke

Write-Host 'Unsetting GHCUP_INSTALL_BASE_PREFIX' -ForegroundColor Green
[Environment]::SetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', $null, [System.EnvironmentVariableTarget]::User)

$ghcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user')
$GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user')

if ($ghcupMsys2) {
  $msys2Dir = [IO.Path]::GetFullPath($ghcupMsys2)
  $baseDir = [IO.Path]::GetFullPath('{0}\ghcup' -f $GhcupBasePrefixEnv)

  if ($msys2Dir.StartsWith($baseDir)) {
    Write-Host 'Unsetting GHCUP_MSYS2' -ForegroundColor Green
    [Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User)
  } else {
    Write-Host ('GHCUP_MSYS2 env variable is set to a non-standard location {0}. Environment variable not unset. Uninstall manually.' -f $msys2Dir) -ForegroundColor Magenta
  }
} else {
  Write-Host 'Unsetting GHCUP_MSYS2' -ForegroundColor Green
  [Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User)
}

Write-Host 'Removing ghcup from PATH env var' -ForegroundColor Green
$path = [System.Environment]::GetEnvironmentVariable(
    'PATH',
    'user'
)
$path = ($path.Split(';') | Where-Object { $_ -ne ('{0}\bin' -f $baseDir) }) -join ';'
[System.Environment]::SetEnvironmentVariable(
    'PATH',
    $path,
    'user'
)

Write-Host 'Removing desktop files' -ForegroundColor Green
$DesktopDir = [Environment]::GetFolderPath("Desktop")
Remove-Item -LiteralPath ('{0}\Install GHC dev dependencies.lnk' -f $DesktopDir) -Force
Remove-Item -LiteralPath ('{0}\Mingw haskell shell.lnk' -f $DesktopDir) -Force
Remove-Item -LiteralPath ('{0}\Mingw package management docs.url' -f $DesktopDir) -Force

Write-Host ('CABAL_DIR env variable is still set to {0} and will be used by cabal regardless of ghcup. You may want to uninstall this manually.' -f [System.Environment]::GetEnvironmentVariable('CABAL_DIR', 'user')) -ForegroundColor Magenta
Write-Host 'You may remove this script now.' -ForegroundColor Magenta

if ($Host.Name -eq "ConsoleHost")
{
    Write-Host "Press any key to continue..."
    $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}
'@

$DesktopDir = [Environment]::GetFolderPath("Desktop")
$GhcInstArgs = '-mingw64 -mintty -c "pacman --noconfirm -S --needed base-devel gettext autoconf make libtool automake python p7zip patch unzip"'
Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe $GhcInstArgs -DestinationPath ('{0}\Install GHC dev dependencies.lnk' -f $DesktopDir)
Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe '-mingw64' -DestinationPath ('{0}\Mingw haskell shell.lnk' -f $DesktopDir)
Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -ArgumentsToSourceExe '' -DestinationPath ('{0}\Mingw package management docs.url' -f $DesktopDir)
$null = New-Item -Path $DesktopDir -Name "Uninstall Haskell.ps1" -ItemType "file" -Force -Value $uninstallShortCut

Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir)
Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User'



$CabalDirFull = [System.IO.Path]::GetFullPath("$CabDirEnv")
Print-Msg -msg ('Setting CABAL_DIR to ''{0}''' -f $CabalDirFull)
$null = [Environment]::SetEnvironmentVariable("CABAL_DIR", $CabalDirFull, [System.EnvironmentVariableTarget]::User)

Print-Msg -msg 'Starting GHCup installer...'

$Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir)

# The bootstrap script is always silent, since we ask relevant questions here
$SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;'

if ($InstallStack) {
  $StackInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_STACK=1 ;'
}

if ($InstallHLS) {
  $HLSInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_HLS=1 ;'
}

if (!($NoAdjustCabalConfig)) {
  $AdjustCabalConfigExport = 'export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=1 ;'
}

if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBash) {
  Exec "$Bash" '-lc' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; [[ ''{0}'' = https* ]]  && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
} else {
  Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} {6} {7} {8} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]]  && curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport)
}


# SIG # Begin signature block
  # MIID4QYJKoZIhvcNAQcCoIID0jCCA84CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
  # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
  # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUVqKek181kF/Jx/P7z176herc
  # ZyCgggH/MIIB+zCCAWSgAwIBAgIQGOezhGS1A5tHh9VubW0liDANBgkqhkiG9w0B
  # AQUFADAYMRYwFAYDVQQDDA1KdWxpYW4gT3NwYWxkMB4XDTIxMDUzMDE4Mzk1OVoX
  # DTI1MDUzMDAwMDAwMFowGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZDCBnzANBgkq
  # hkiG9w0BAQEFAAOBjQAwgYkCgYEAs76XCXYPM14buR1RkVKhOB8pyM4Df6kPaz75
  # nkbA0nq1VmMhBfCYFWyYHd7jniqTH0LoAKGGquN1bniREaCP9j2pFWpMIgLpQH3H
  # +jpsfmxV2BTG8q+Jok88gTXS1FlAk72E85zO/Jhr6Fja1aFYAdibBRsRxcVMTVh7
  # 4AGLNGUCAwEAAaNGMEQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFC+R
  # hdhPo0Ty5HnzHyo1pN35IfZQMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUF
  # AAOBgQAl3IdBVIwbJJDp7BksMYPeM4ivB3UyNvlw8aVxGwAzNgdSaezYIdMFtKXV
  # CSv5bd4VnFRAPDJW9dhW0h3SkeJUoklUxMjKXhR3qygQhSxPDjIatAuOCffGACba
  # ZZ7Om40b+pKXc6i/HnlApk9DGbXJ59bFcLGGcZ9QjoUae6Ex1DGCAUwwggFIAgEB
  # MCwwGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZAIQGOezhGS1A5tHh9VubW0liDAJ
  # BgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B
  # CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAj
  # BgkqhkiG9w0BCQQxFgQUosm9nN1JgajqSBa1cUwxxhLrAsYwDQYJKoZIhvcNAQEB
  # BQAEgYCnKzfsH1aDjS6xkC/uymjaBowHSnh6nFu2AkjcKu8RgcBZzP5SLBXgU9wm
  # aED5Ujwyq3Qre+TGVRUqwkEauDhQiX2A008G00fRO6+di6yJRCRn5eaRAbdU3Xww
  # E5VhEwLBnwzWrvLKtdEclhgUCo5Tq87QMXVdgX4aRmunl4ZE+Q==
# SIG # End signature block