<#
.DESCRIPTION
    Script to install python and start the bootstrap.py.
    This file was generated by yanga.
    VERSION: {{ bootstrap_version }}
#>

$ErrorActionPreference = "Stop"

###################################################################################################
# Configuration
###################################################################################################
$bootstrapJsonPath = Join-Path $PSScriptRoot "bootstrap.json"
if (Test-Path $bootstrapJsonPath) {
    $json = Get-Content $bootstrapJsonPath | ConvertFrom-Json
    $config = @{
        pythonVersion = $json.python_version
        scoopInstaller = $json.scoop_installer
        scoopMainBucketBaseUrl = $json.scoop_main_bucket_base_url
        scoopPythonBucketBaseUrl = $json.scoop_python_bucket_base_url
    }
} else {
    $config = @{
        pythonVersion = "{{ python_version }}"
        scoopInstaller = "{{ scoop_installer }}"
        scoopMainBucketBaseUrl = "{{ scoop_main_bucket_base_url }}"
        scoopPythonBucketBaseUrl = "{{ scoop_python_bucket_base_url }}"
    }
}

###################################################################################################
# Utility functions
###################################################################################################

# Update/Reload current environment variable PATH with settings from registry
Function Initialize-EnvPath {
    # workaround for system-wide installations
    if ($Env:USER_PATH_FIRST) {
        $Env:Path = [System.Environment]::GetEnvironmentVariable("Path", "User") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "Machine")
    }
    else {
        $Env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
    }
}

Function Invoke-CommandLine {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = 'Usually this statement must be avoided (https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/avoid-using-invoke-expression?view=powershell-7.3), here it is OK as it does not execute unknown code.')]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$CommandLine,
        [Parameter(Mandatory = $false, Position = 1)]
        [bool]$StopAtError = $true,
        [Parameter(Mandatory = $false, Position = 2)]
        [bool]$Silent = $false
    )
    if (-Not $Silent) {
        Write-Output "Executing: $CommandLine"
    }
    $global:LASTEXITCODE = 0
    Invoke-Expression $CommandLine
    if ($global:LASTEXITCODE -ne 0) {
        if ($StopAtError) {
            Write-Error "Command line call `"$CommandLine`" failed with exit code $global:LASTEXITCODE"
        }
        else {
            if (-Not $Silent) {
                Write-Output "Command line call `"$CommandLine`" failed with exit code $global:LASTEXITCODE, continuing ..."
            }
        }
    }
}

Function Install-Scoop {
    # Initial Scoop installation
    if (-Not (Get-Command 'scoop' -ErrorAction SilentlyContinue)) {
        $tempDir = [System.IO.Path]::GetTempPath()
        $tempFile = "$tempDir\install.ps1"
        Invoke-RestMethod $config.scoopInstaller -OutFile $tempFile
        if ((New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
            & $tempFile -RunAsAdmin
        }
        else {
            & $tempFile
        }
        Initialize-EnvPath
        Remove-Item $tempFile
    }

    # Install needed tools
    Invoke-CommandLine "scoop update"
    # Avoid deadlocks while updating scoop buckets
    Invoke-CommandLine "scoop config autostash_on_conflict $true" -Silent $true

    Initialize-EnvPath
}

###################################################################################################
# Main
###################################################################################################

# python executable name
$python = "python" + $config.pythonVersion.Replace(".", "")

# Check if scoop is installed
$scoopPath = (Get-Command scoop -ErrorAction SilentlyContinue).Source
if ($scoopPath -eq $null) {
    Write-Output "Scoop not found. Trying to install scoop ..."
    Install-Scoop
}
else {
    Write-Output "Found scoop under $scoopPath."
}
# Check if python is installed
$pythonPath = (Get-Command $python -ErrorAction SilentlyContinue).Source
if ($pythonPath -eq $null) {
    Write-Output "$python not found. Try to install $python via scoop ..."
    # Install Python installer dependencies
    Invoke-CommandLine "scoop install $($config.scoopMainBucketBaseUrl)/dark.json"
    Invoke-CommandLine "scoop install $($config.scoopMainBucketBaseUrl)/lessmsi.json"
    # Install python
    Invoke-CommandLine "scoop install $($config.scoopPythonBucketBaseUrl)/$python.json"
}
else {
    Write-Output "$python found in $pythonPath"
    # Extract the directory of python exe file and add it to PATH. It needs to be the first entry in PATH
    # such that this version is used when the user calls python and not python311
    $pythonDir = [System.IO.Path]::GetDirectoryName($pythonPath)
    Write-Output "Adding $pythonDir to PATH"
    $Env:Path += ";$pythonDir"
}

# Call the bootstrap.py if it exists with all provided arguments
$buildScript = Join-Path $PSScriptRoot "bootstrap.py"
if (Test-Path $buildScript) {
    Write-Output "Calling $buildScript ..."
    & $python $buildScript $args
}
