# WizardKit: Build base kit

## Init ##
#Requires -Version 3.0
[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True)]
    [string]$KitPath
)
if (Test-Path Env:\DEBUG) {
  Set-PSDebug -Trace 1
}
$Host.UI.RawUI.WindowTitle = "WizardKit: Build Tool"
$WD = Split-Path $MyInvocation.MyCommand.Path | Get-Item
$Root = Get-Item "$KitPath"
$Bin = Get-Item "$($Root.FullName)\.bin" -Force
$Temp = "$Bin\tmp"
$System32 = "{0}\System32" -f $Env:SystemRoot
$SysWOW64 = "{0}\SysWOW64" -f $Env:SystemRoot
Push-Location "$WD"
$Host.UI.RawUI.BackgroundColor = "black"
$Host.UI.RawUI.ForegroundColor = "white"
#Enable TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


## Functions ##
function Abort {
  Write-Host -ForegroundColor "Red" "`nAborted."
  WKPause "Press Enter to exit..."
  exit
}
function DownloadFile ($Path, $Name, $Url) {
  $OutFile = "{0}\{1}" -f $Path, $Name

  Write-Host ("Downloading: $Name")
  New-Item -Type Directory $Path 2>&1 | Out-Null
  try {
    Invoke-WebRequest -Uri $Url -OutFile $OutFile
  }
  catch {
    Write-Host ("  ERROR: Failed to download file." ) -ForegroundColor "Red"
    $global:DownloadErrors += 1
  }
}
function FindDynamicUrl ($SourcePage, $RegEx) {
  # Get source page
  Invoke-Webrequest -Uri $SourcePage -OutFile "tmp_page"

  # Search for real url
  $Url = Get-Content "tmp_page" | Where-Object {$_ -imatch $RegEx}
  $Url = $Url -ireplace '.*(a |)href="([^"]+)".*', '$2'
  $Url = $Url -ireplace ".*(a |)href='([^']+)'.*", '$2'

  # Remove tmp_page
  Remove-Item "tmp_page"

  $Url | Select-Object -First 1
}
function WKPause ($Message = "Press Enter to continue... ") {
  Write-Host $Message -NoNewLine
  Read-Host
}

## Safety Check ##
if ($PSVersionTable.PSVersion.Major -eq 6 -and $PSVersionTable.OS -imatch "Windows 6.1") {
  Write-Host "`nThis script doesn't support PowerShell 6.0 on Windows 7."
	Write-Host "Press Enter to exit... " -NoNewLine
  Abort
}

## PowerShell equivalent of Python's "if __name__ == '__main__'"
# Code based on StackOverflow comments
# Question:     https://stackoverflow.com/q/4693947
# Using answer: https://stackoverflow.com/a/5582692
# Asked by:     https://stackoverflow.com/users/65164/mark-mascolino
# Answer by:    https://stackoverflow.com/users/696808/bacon-bits
if ($MyInvocation.InvocationName -ne ".") {
  Clear-Host
  Write-Host "WizardKit: Build Tool`n`n`n`n`n"

  ## Sources ##
  $Sources = Get-Content -Path "$WD\sources.json" | ConvertFrom-JSON

  ## Download ##
  $DownloadErrors = 0

  # 7-Zip
  DownloadFile -Path $Temp -Name "7z-installer.msi" -Url $Sources.'7-Zip'

  # ConEmu
  DownloadFile -Path $Temp -Name "ConEmuPack.7z" -Url $Sources.'ConEmu'

  # Python
  DownloadFile -Path $Temp -Name "python32.zip" -Url $Sources.'Python x32'
  DownloadFile -Path $Temp -Name "python64.zip" -Url $Sources.'Python x64'

  # Python: docopt
  Copy-Item -Path "$WD\docopt\docopt-0.6.2-py2.py3-none-any.whl" -Destination "$Temp\docopt.whl"

  # Python: mariadb
  $DownloadPage = "https://pypi.org/project/mariadb"
  $RegEx = "href=.*-cp310-cp310-win32.whl"
  $Url = FindDynamicUrl $DownloadPage $RegEx
  DownloadFile -Path $Temp -Name "mariadb32.whl" -Url $Url
  $RegEx = "href=.*-cp310-cp310-win_amd64.whl"
  $Url = FindDynamicUrl $DownloadPage $RegEx
  DownloadFile -Path $Temp -Name "mariadb64.whl" -Url $Url

  # Python: psutil
  $DownloadPage = "https://pypi.org/project/psutil/"
  $RegEx = "href=.*-cp36-abi3-win32.whl"
  $Url = FindDynamicUrl $DownloadPage $RegEx
  DownloadFile -Path $Temp -Name "psutil32.whl" -Url $Url
  $RegEx = "href=.*-cp36-abi3-win_amd64.whl"
  $Url = FindDynamicUrl $DownloadPage $RegEx
  DownloadFile -Path $Temp -Name "psutil64.whl" -Url $Url

  # Python: prompt_toolkit, pytz, requests, & dependancies
  $RegEx = "href=.*.py3-none-any.whl"
  foreach ($Module in @("certifi", "chardet", "idna", "packaging", "prompt_toolkit", "Pygments", "pytz", "requests", "urllib3", "wcwidth")) {
    $DownloadPage = "https://pypi.org/project/$Module/"
    $Name = "$Module.whl"
    $Url = FindDynamicUrl -SourcePage $DownloadPage -RegEx $RegEx
    DownloadFile -Path $Temp -Name $Name -Url $Url
  }

  ## Bail ##
  # If errors were encountered during downloads
  if ($DownloadErrors -gt 0) {
    Abort
  }

  ## Extract ##
  # 7-Zip
  Write-Host "Extracting: 7-Zip"
  try {
    $ArgumentList = @("/a", "$Temp\7z-installer.msi", "TARGETDIR=$Temp\7zi", "/qn")
    Start-Process -FilePath "$System32\msiexec.exe" -ArgumentList $ArgumentList -Wait
    New-Item -Type Directory $Bin\7-Zip 2>&1 | Out-Null
    Move-Item "$Temp\7zi\Files\7-Zip\7z.dll" "$Bin\7-Zip\7z.dll"
    Move-Item "$Temp\7zi\Files\7-Zip\7z.exe" "$Bin\7-Zip\7z.exe"
    Move-Item "$Temp\7zi\Files\7-Zip\License.txt" "$Bin\7-Zip\License.txt"
    Remove-Item "$Temp\7z*" -Recurse
    $SevenZip = "$Bin\7-Zip\7z.exe"
  }
  catch {
    Write-Host ("  ERROR: Failed to extract files." ) -ForegroundColor "Red"
  }

  # ConEmu
  Write-Host "Extracting: ConEmu"
  try {
    $ArgumentList = @(
      "x", "$Temp\ConEmuPack.7z", "-o$Bin\ConEmu",
      "-aoa", "-bso0", "-bse0", "-bsp0")
    Start-Process -FilePath $SevenZip -ArgumentList $ArgumentList -NoNewWindow -Wait
    Remove-Item "$Temp\ConEmuPack.7z"
  }
  catch {
    Write-Host ("  ERROR: Failed to extract files." ) -ForegroundColor "Red"
  }

  # Python
  foreach ($Arch in @("32", "64")) {
    Write-Host "Extracting: Python (x$Arch)"
    $Files = @(
      "Pygments.whl",
      "certifi.whl",
      "chardet.whl",
      "docopt.whl",
      "idna.whl",
      "mariadb$Arch.whl",
      "packaging.whl",
      "prompt_toolkit.whl",
      "psutil$Arch.whl",
      "python$Arch.zip",
      "pytz.whl",
      "requests.whl",
      "urllib3.whl",
      "wcwidth.whl"
    )
    try {
      foreach ($File in $Files) {
        $ArgumentList = @(
          "x", "$Temp\$File", "-o$Bin\Python\x$Arch",
          "-aoa", "-bso0", "-bse0", "-bsp0")
        Start-Process -FilePath $SevenZip -ArgumentList $ArgumentList -NoNewWindow -Wait
      }
    }
    catch {
      Write-Host ("  ERROR: Failed to extract files." ) -ForegroundColor "Red"
    }
  }
  Remove-Item "$Temp\python*.zip"
  Remove-Item "$Temp\*.whl"
  foreach ($File in Get-ChildItem "$Bin\Python\*\*._pth") {
    Add-Content "$File" "`n#WizardKit`n..\..\Scripts"
  }

  ## Done ##
  Pop-Location
  if ([System.Environment]::Is64BitOperatingSystem) {
    $ConEmu = "$Bin\ConEmu\ConEmu64.exe"
    $Python = "$Bin\Python\x64\python.exe"
  } else {
    $ConEmu = "$Bin\ConEmu\ConEmu.exe"
    $Python = "$Bin\Python\x32\python.exe"
  }
  $ArgumentList = @("-run", "$Python", "$Bin\Scripts\build_kit_windows.py", "-new_console:n")
  Start-Process -FilePath "$ConEmu" -ArgumentList $ArgumentList -verb RunAs
}
