UniversalAutomation.psm1

Import-Module "$PSScriptRoot\UniversalAutomation.Cmdlets.dll"
[UniversalAutomation.AssemblyResolver]::Bind()

function Start-UAServer  {
    param(
        [Parameter()]
        [string]$Port = 10000,
        [Parameter()]
        [string]$ConnectionString = "$Env:LOCALAPPDATA\UniversalAutomation\database.db",
        [Parameter()]
        [string]$GitRemote,
        [Parameter()]
        [PSCredential]$GitRemoteCredential,
        [Parameter()]
        [string]$JwtSigningKey = "UniversalAutomationSigningKey",
        [Parameter()]
        [string]$JwtAudience = "UniversalAutomation",
        [Parameter()]
        [string]$JwtIssuer = "Ironman Software",
        [Parameter()]
        [string]$LocalComputerName = "localhost",
        # [Parameter()]
        # [string]$Certificate,
        [Parameter()]
        [string]$CertificateFile,
        [Parameter()]
        [SecureString]$CertificatePassword,
        [Parameter()]
        [Switch]$InProcess
    )

    $Process = Get-Process -Id $Pid
    $HostProcess = $Process.MainModule.FileName

    if ($GitRemote)
    {
        $Env:GitRemote = $GitRemote
    }

    if ($GitRemoteCredential)
    {
        $Env:GitRemoteUserName = $GitRemoteCredential.UserName
        $Env:GitRemotePassword = $GitRemoteCredential.GetNetworkCredential().Password
    }

    $Env:UAJWTSigningKey = $JwtSigningKey
    $Env:UAJWTAudience = $JwtAudience
    $Env:UAJWTIssuer = $JwtIssuer

    $Env:UACertificate = $Certificate
    $Env:UACertificateFile = $CertificateFile

    if ($CertificatePassword)
    {
        $s = New-Object PSCredential -ArgumentList "test", $CertificatePassword
        $Env:UACertificatePassword = $s.GetNetworkCredential().Password
    }

    $AliveKey = New-Guid

    $StartUpScript = {
        try { 
            [System.Reflection.Assembly]::LoadFrom('$PSScriptRoot/UniversalAutomation.dll') | Out-Null;
            [System.Reflection.Assembly]::LoadFrom('$PSScriptRoot/UniversalAutomation.Common.dll') | Out-Null;
            [UniversalAutomation.AssemblyResolver]::Bind();
    
            if ($null -eq ([UniversalAutomation.PersistenceService]::Configuration))
            {
                Import-Module '$PSScriptRoot/UniversalAutomation.LiteDB.psd1';
                Use-UALiteDB -ConnectionString '$ConnectionString';
            }
    
            [UniversalAutomation.EntryPoint]::Start('$Port', $true, '$AliveKey'); 
        } catch { 
            $_.Exception.Message;
            $_.Exception.InnerException.StackTrace;
        }
    }

    $Script = $StartUpScript.ToString().Replace([Environment]::NewLine, '');
    $Script = $Script.Replace('$PSScriptRoot', $PSScriptRoot);
    $Script = $Script.Replace('$Port', $Port);
    $Script = $Script.Replace('$AliveKey', $AliveKey);
    $Script = $Script.Replace('$ConnectionString', $ConnectionString);

    if ($InProcess)
    {
        $Runspace = [RunspaceFactory]::CreateRunspace()
        $Runspace.Open() | Out-Null
        $PowerShell = [powershell]::Create()
        $PowerShell.AddScript($Script) | Out-Null
        $PowerShell.Runspace = $Runspace
        $PowerShell.BeginInvoke() | Out-Null

        $Script:UAServer = $PowerShell
    }
    else 
    {
        $Script:UAServer = Start-Process -FilePath $HostProcess -ArgumentList "-NoExit -NoProfile -Command `"& {$Script}`"" -PassThru 
    }

    $Retries = 0

    while($Retries -le 100)
    {
        try 
        {
            (Invoke-WebRequest "http://$LocalComputerName"+":"+"$port/api/v1/alive" -Headers @{ AliveKey = $AliveKey } -UseBasicParsing).Content
            break
        }
        catch {}
        Start-Sleep -Milliseconds 100
        $Retries++
    }

    if ($Retries -eq 100)
    {
        throw "Failed to start Universal Automation server"
    }
}

function Stop-UAServer 
{
    if ($Script:UAServer -is [PowerShell])
    {
        $Script:UAServer.EndInvoke() | Out-Null
    }
    else 
    {
        $Script:UAServer.Kill()
    }
}

function Debug-UAJob
{
    param(
        [Parameter(ValueFromPipeline = $true, Mandatory)]
        $Job
    )

    Process 
    {
        Enter-PSHostProcess -Id $Job.ProcessId 
        Debug-Runspace -Id $Job.RunspaceId
    }
}

function Publish-UAService
{
    param(
        [Parameter()]
        $ServiceName = "UniversalAutomation",
        [Parameter()]
        $PowerShellPath = (Get-Command PowerShell).Path,
        [Parameter()]
        $PowerShellArguments = @(),
        [Parameter()]
        [int]$Port = 80,
        [Parameter()]
        [ValidateSet("x64", "x86")]
        [string]$Architecture = 'x64'
    )

    $nssm = [IO.Path]::Combine($PSScriptRoot, 'nssm', $Architecture, 'nssm')

    & $nssm install $ServiceName $PowerShellPath 
}

New-Alias -Name 'Receive-UAJob' -Value 'Get-UAJobPipelineOutput'