
$Global:IsRunningUnderAxe = $false 
Export-ModuleMember -Variable IsRunningUnderAxe


#### AXE environment variables ####
try 
{
    $Global:AXEResultsPath = (Get-Item env:\AssessmentResultsPath -ErrorAction Stop).value
    $Global:AXEExecutionPath = (Get-Item env:\AssessmentExecutionPath -ErrorAction Stop).value
    $Global:AXETempPath = (Get-Item env:\AssessmentTempPath -ErrorAction Stop).value
    $AxeBinPath = (Get-Item env:\AssessmentAxeBinPath -ErrorAction Stop).value
    $AxeCoreNet = "$AxeBinPath\Microsoft.Assessments.Core.dll"
}
catch
{
    throw "Unable to get Axe environment variables."
}


# **********************************************************
#                     AXE SETUP
# **********************************************************

#### install AXE ETW manifest ####
function RegisterAxeETWManifest
{
    wevtutil um "$AxeBinPath\axeetw.man"
    icacls "$AxeBinPath\axeetw.man" /t /grant Everyone:R
    icacls "$AxeBinPath\axecore.dll" /t /grant Everyone:R
    wevtutil im "$AxeBinPath\axeetw.man" /rf:"$AxeBinPath\axecore.dll" /mf:"$AxeBinPath\axecore.dll"
}

RegisterAxeETWManifest

#
# Load up AXE framework from AXE DLL
# Initialize Runtime and create Logger helper object
#
if ($AxeCoreNet -and (Test-Path $AxeCoreNet) )
{
    $axeAssembly = [Reflection.Assembly]::LoadFrom( $AxeCoreNet )

    if ( $axeAssembly )
    {
        $axeSupport = [Microsoft.Assessments.Runtime.Support]::Initialize()

        if ( $axeSupport )
        {
            $Global:IsRunningUnderAxe = $axeSupport.EngineRunning
            $axeLogger = $axeSupport.CreateLogger()
        }
    }
}


# **********************************************************
#                 AXE HELPER FUNCTIONS
# **********************************************************

# This function will write what is piped to it as a string to the default output
# (usually the host/console) and also to the log file if running under axe.
#
function Out-AxeInfo { PROCESS {
    if ( $_ ) {
        "$_" | Out-Default
        if ( $axeLogger ) {
            $axeLogger.LogMessage( "$_" )
        }
    }
}}

# This function will write what is piped to it as a string as an error
# and also to the log file if running under axe.
#
function Out-AxeError([int32]$ErrorCode=1) { PROCESS {
    if ( $_ ) {
        "$_" | Write-Error
        if ( $axeLogger ) {
            $axeLogger.LogErrorCode( $ErrorCode, "$_" )
        }
    }
}}

function Start-AxeReboot
{
    $axeSupport.ReportProgress( [Microsoft.Assessments.AxeProgressType]::OnOff, 0, "Restart assessment." )
}

function Trace-AxeOperationStart {
param (
    [parameter(Mandatory=$true)][int32]$OpCode,
    [parameter(Mandatory=$true)][string]$Payload
)

    $axeLogger.LogBeginOperation($OpCode, $Payload, '')
}

function Trace-AxeOperationStop {
param (
    [parameter(Mandatory=$true)][int32]$OpCode,
    [parameter(Mandatory=$true)][string]$Payload
)

    $axeLogger.LogEndOperation($OpCode, $Payload, '')
}


function Get-AxeResultSnippet
{
    return $axeSupport.CreateResultSnippet()
}

function Start-AxeCleanup
{
    if ( $axeSupport )
    {
        $axeSupport.Dispose()
    }
}

function Update-AxeProgress {
param (
    [parameter(Mandatory=$true)][int32]$Percent,
    [parameter(Mandatory=$true)][string]$Message
)

    $axeSupport.ReportProgress( [Microsoft.Assessments.AxeProgressType]::Percent, $Percent, $Message )

}


# Make sure we've set up the environment properly
#
if ( -not $Global:IsRunningUnderAxe )
{
    "This module only works when loaded under the Axe framework." | Out-AxeError
    Exit 1
}

Export-ModuleMember -Variable AXEResultsPath
Export-ModuleMember -Variable AXETempPath

Export-ModuleMember -Function Out-AxeError
Export-ModuleMember -Function Out-AxeInfo 
Export-ModuleMember -Function Start-AxeReboot
Export-ModuleMember -Function Start-AxeCleanup
Export-ModuleMember -Function Get-AxeResultSnippet
Export-ModuleMember -Function Trace-AxeOperationStop
Export-ModuleMember -Function Trace-AxeOperationStart
Export-ModuleMember -Function Update-AxeProgress