Integrom.Module.Bootstrap.psm1

$dynamicEnumBlock = @"
   public enum %%ENUM_NAME%% {
      %%ENUM_DATA%%
   }
"@


$IntegromLibraryExtension = 'psil'

function getPossibleLibPaths{param([string]$libName, [string]$baseLibPath)
   [string[]]$pathSuffixes = '', '_lib\'
   [string[]]$result = @()

   if (-not [string]::IsNullOrEmpty($baseLibPath) -and -not ($baseLibPath -match '\\$')) {$baseLibPath = "$($baseLibPath)\"}
   
   $regexResult = [regex]::Match("$($baseLibPath)$($libName)", '(?<root>^[a-z]:|/|\.\.|\.|\\\\|(?:http|ftp|https|sftp)(://))?(?<path>.*(\\|/))?((?<libName>.+)(?<ext>\.psil$)|(?<libName>.+))', [Text.RegularExpressions.RegexOptions]::IgnoreCase)
   $root = $regexResult[0].Groups['root'].value
   $path = $regexResult[0].Groups['path'].value
   $libSname = $regexResult[0].Groups['libName'].value
   if ([string]::IsNullOrEmpty($root)) {$rootsToTest = '.\', '..\', "$($env:ProgramFiles)\Integrom\Libraries\"} else {$rootsToTest = $root}
   $pathSuffixes += "$($libSname)\"
   foreach ($rootEntry in $rootsToTest) {
      foreach ($pathSuffix in $pathSuffixes) {
         $result += "$($rootEntry)$($path)$($pathSuffix)$($libSname).$($IntegromLibraryExtension)"
      }
   }
   return $result
}

function loadLibraries {[CmdletBinding()]param([string[]]$libraryNames, [string]$libPath)
   # [CmdletBinding()] is necessary to get the correct session state to load the library into
   if ($libraryNames.Count -lt 1) {return -5}

   [int]$statusCode = 0
   foreach ($libraryName in $libraryNames) {
      Write-Host "INFO: Loading library $($libraryName)...."
      foreach ($fqLibPath in (getPossibleLibPaths -libName $libraryName -baseLibPath $libPath)) {
         try {
            $ExecutionContext.SessionState.InvokeCommand.InvokeScript($PSCmdlet.SessionState, {param($libName); Invoke-Expression -Command ((Get-Content -Path $libName -Raw) -replace '%%PSIL_LOCATION%%', ($libName -replace '(?:\\|/)[^\\|/]+$', ''))}.Ast.GetScriptBlock(), $fqLibPath)
            $libLoaded = $true
         } catch {
            $libLoaded = $false
            continue
         }
         if ($libLoaded) {break}
      }
      if (-not $libLoaded) {
         $statusCode = -20
         Write-host "WARNING: Failed to load library $($libraryName) from all known location(s)."
      }
   }
   return $statusCode
}

function getLibraryVersion{[CmdletBinding()]param([string]$libraryName, [string]$libPath)
   #cmdletbinding probably not needed here
   foreach ($fqLibPath in (getPossibleLibPaths -libName $libraryName -baseLibPath $libPath)) {
      try {
         $null = Invoke-Command {$fqLibPath} -NoNewScope
         return $Version
      } catch {
         continue
      }
   }
   return -1
}

function injectEnumFromJSON{[CmdletBinding()]param([string]$jsonFile, [string]$jsonKey, [string]$enumDef = $dynamicEnumBlock)
   # [CmdletBinding()] is necessary to get the correct session state to inject the Enum into
   [int]$v = 4001
   [scriptblock]$unboundCode = {param([string]$enumdef); Add-Type -TypeDefinition $enumdef}.Ast.GetScriptBlock()
   [PSCustomObject]$jsonFileData = Get-Content $jsonfile | ConvertFrom-Json
   if (($jsonFileData.$jsonKey).count -lt 1) {return -5}
   foreach ($item in $jsonFileData.$jsonKey) {$enumItems += "@$($item) = $($v),`n"; $v ++}
   $enumDef = $enumDef`
      -replace '%%ENUM_NAME%%', $jsonKey`
      -replace '%%ENUM_DATA%%', $enumItems
   try {
      $ExecutionContext.SessionState.InvokeCommand.InvokeScript($PSCmdlet.SessionState, $unboundCode, $enumDef)
      return 0
   } catch {
      return -17
   }
}