<#
.SYNOPSIS
    Modern Standby Performance Assessment

.DESCRIPTION
    Automates Modern Standby power transitions and measures entry/exit latency metrics

.PARAMETER iterations
    Number of Modern Standby transitions to automate
.PARAMETER sleeptimeout_sec
    Duration in seconds of the Modern Standby session
.PARAMETER postdelay_sec
    Delay in seconds between iterations
.PARAMETER NetworkingState
    Disconnected standby
.PARAMETER disablequiethours
    Disable the OS Quiet Hours feature before entering Modern Standby
.PARAMETER modeaggressive
    Enable aggressive mode during disconnected standby
.PARAMETER simulatedbatteries
    Simulate batteries without unplugging the AC power
.PARAMETER enablepowerlogs
    Select to gather additional power related log files for diagnostics
.PARAMETER traceprofile
    Alternate WPRP tracing profile
.PARAMETER DebugFlag
    Pause at the end of the script to allow diagnostics of console output
.PARAMETER ConfigJson
    Alternate JSON configuration file
#>
Param( 
    [parameter(Mandatory=$false)][int32]$iterations,
    [parameter(Mandatory=$false)][int32]$sleeptimeout_sec,
    [parameter(Mandatory=$false)][int32]$postdelay_sec,
    [parameter(Mandatory=$false)][int32]$NetworkingState,
    [parameter(Mandatory=$false)][switch]$disablequiethours,
    [parameter(Mandatory=$false)][switch]$modeaggressive,
    [parameter(Mandatory=$false)][switch]$simulatedbatteries,
    [parameter(Mandatory=$false)][switch]$enablepowerlogs,
    [parameter(Mandatory=$false)][string]$traceprofile,
    [parameter(Mandatory=$false)][switch]$DebugFlag,
    [parameter(Mandatory=$false)][switch]$DirtyModernStandby,
    [parameter(Mandatory=$false)][switch]$EnableLockScreen,
    [parameter(Mandatory=$false)][switch]$EnablePinAutomation,
    [parameter(Mandatory=$false)][string]$UserName,
    [parameter(Mandatory=$false)][string]$PIN,
    [parameter(Mandatory=$true)][string]$ConfigJson,
    [parameter(Mandatory=$false)][switch]$EnableStressTest
)
try
{
    $SimBattInstalled = $false
    $SimBattDisableRealBatteries = $false
    $SimBattToDC = $false

    # Need to know where our script is so we can use full path to all our dependent files.
    $InvocationPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
    $AxeUniversalPath = Convert-Path((Get-Item env:\AssessmentAxeUniversalPath).value)
	
    try
    {
        # Import the modules and functions
        Import-Module "$AxeUniversalPath\UniversalAssessment.psm1" -ErrorAction Stop
    }
    catch
    {
        throw "Failed to import $AxeUniversalPath\UniversalAssessment.psm1"
    }
    Initialize-UniversalFramework -InvocationPath (Split-Path -Path $MyInvocation.MyCommand.Path -Parent) -AxeUniversalPath $AxeUniversalPath

    # Configuration JSON file
    try {
        $IniJSON =  Get-Content -Raw -Path $ConfigJson | ConvertFrom-Json
    }
    catch {
        Throw "Unable to load JSON config file ($ConfigJson)"
    }

    #subfolders
    $ModulesPath = Join-Path -path $InvocationPath modules
	
    #Import AXE support helper module
    Import-Module "$ModulesPath\CommonSystem.psm1" -ErrorAction Stop

    #Import simulate batteries module
    Import-Module "$ModulesPath\SimBattPSHelper.psm1" -ErrorAction Stop

    # Import power logs helper module
    Import-Module "$ModulesPath\PowerLogsPSHelper.psm1" -ErrorAction Stop

    # Import powercfg helper module
    Import-Module "$ModulesPath\PowerCfgPSHelper.psm1" -ErrorAction Stop

    # Tools and resources
    $realarch              = Get-RealProcessorArchitecture

    $powershellArch  = Get-PowerShellArchitecture
    if ($powershellArch -eq "arm64") {
        $powershellArch = "amd64"
    }
    $InvocationArch  = Join-Path -path $InvocationPath $powershellArch
    $env:path        = "$InvocationArch;" + "$InvocationPath;" + $env:path

    $StabDelay = $IniJSON.Execution.StabilizationDelaySec

    # Path for process execution logs (err and std outputs)
    $LogsPath = join-path -path $AXEResultsPath logs
    if (-not (test-path $LogsPath))
    {
        New-Item $LogsPath -ItemType directory > $null
    }

    if ($EnablePinAutomation)
    {
        $credentialsJsonFile = "$InvocationPath\credentials.json"
        Update-UserNameAndPINFromJson -credentialsJsonFile $credentialsJsonFile -UserName ([ref]$UserName) -PIN ([ref]$PIN)

        [string[]]$CustomPackages = @("Microsoft-Assessments-Core-LogonUXAutomation.cab")
        Install-UT_TaefPackages -arch $realarch -CabsPath $AxeCabsPath -BinariesPath $BinariesPath -CustomPackages $CustomPackages
    }
    
    if ($EnableStressTest)
    {
        [string[]]$CustomPackages = @("Microsoft-Assessments-Core-Session0Launcher.cab")
        Install-UT_TaefPackages -arch $realarch -CabsPath $AxeCabsPath -BinariesPath $BinariesPath -CustomPackages $CustomPackages
    }


    ######################################
    #
    #   Execution
    #
    ######################################

    if ($DirtyModernStandby)
    {
        $idAmazon = Start-Process -FilePath https://www.amazon.com -PassThru
        start-sleep -Seconds 1
        Start-Process -FilePath https://youtu.be/16mHR2wHiwI?t=1
        start-sleep -Seconds 1
        Start-Process -FilePath https://en.wikipedia.org/wiki/United_States
        start-sleep -Seconds 1
        
        $MailApp = ((New-Object -ComObject Shell.Application).NameSpace("shell:appsfolder").Items() | Where-Object { $_.Name -eq "Mail"})
        if ($MailApp -ne $null)
        {
            explorer shell:AppsFolder\$($MailApp.Path)
        }
        else
        {
            "WARNING: Unable to find Mail app for DirtyModernStandby option" | Log-Info
        }
    }
    
    try
    {
        if ($simulatedbatteries)
        {
            # change directory to make SimBattCtl.exe happy
            Set-Location -Path "$InvocationPath\$realarch"
            # Install simulated batteries
            "Install simulated batteries" | Log-Info
            Invoke-SimBattCtl -StageMessage "Install simulated batteries" `
                -Option "-i" -LogsPath "$LogsPath"
            $SimBattInstalled = $true

            # Disable all real batteries
            "Disable all real batteries" | Log-Info
            Invoke-SimBattCtl -StageMessage "Disable all real batteries" `
                -Option "-x" -LogsPath "$LogsPath"
            $SimBattDisableRealBatteries = $true

            # Set simulated batteries to DC power
            "Set simulated batteries to DC power" | Log-Info
            Invoke-SimBattCtl -StageMessage "Set simulated batteries to DC power" `
                -Option "-d" -LogsPath "$LogsPath"
            $SimBattToDC = $true
        }

        "Sleeping $StabDelay seconds for stabilization" | Log-Info 
        start-sleep -Seconds $StabDelay

        # Launch the ConnectedStandby automation binary
        "Launching ModernStandby automation for $iterations iterations" | Log-Info
        Start-Process "$InvocationPath\$realarch\ConnectedStandby.exe" `
            -ArgumentList "/sleeptimeout_sec $sleeptimeout_sec /iterations $iterations /postonoffsec $postdelay_sec /NetworkingState $NetworkingState /resultspath `"$AXEResultsPath`" /axebinpath `"$env:AssessmentAxeBinPath`" $(if($disablequiethours) {"/disablequiethours"}) $(if($modeaggressive) {"/modeaggressive"}) $(if($EnableLockScreen) {"/EnableLockScreen"}) $(if($EnablePinAutomation) {"/EnablePinAutomation /UserName $UserName /PIN $PIN"}) $(if($EnableStressTest) {"/EnableStressTest"})" `
            -Wait `
            -RedirectStandardError "$LogsPath\ms_timing_err.txt" `
            -RedirectStandardOutput "$LogsPath\ms_timing_std.txt" `
            -NoNewWindow
        
        # add Regions of Interest XML file in the JobResults folder
        $ResourcesPath = Join-Path -path $InvocationPath resources
        Copy-Item $ResourcesPath\ModernStandby.Regions.xml $AXEResultsPath -Force
        Copy-Item $ResourcesPath\ModernStandby.wpaProfile $AXEResultsPath -Force
    }
    catch
    {
        throw
    }
    finally
    {
        # Uninstall simulated batteries before starting power logs to avoid
        # uninstallation (of simulated batteries) failure
        if ($SimBattToDC)
        {
            # Set simulated batteries to AC power
            "Set simulated batteries to AC power" | Log-Info
            $err = Invoke-SimBattCtl -StageMessage "Set simulated batteries to AC power" `
                -Option "-a" -LogsPath "$LogsPath" `
                -ThrowOnError $false
            if ($err.length -ne 0)
            {
                "$err" | Log-Info
            }
        }

        if ($SimBattDisableRealBatteries)
        {
            # Enable all real batteries
            "Enable all real batteries" | Log-Info
            $err = Invoke-SimBattCtl -StageMessage "Enable all real batteries" `
                -Option "-e" -LogsPath "$LogsPath" `
                -ThrowOnError $false
            if ($err.length -ne 0)
            {
                "$err" | Log-Info
            }
        }

        if ($SimBattInstalled)
        {
            # Uninstall simulated batteries
            "Uninstall simulated batteries" | Log-Info
            $err = Invoke-SimBattCtl -StageMessage "Uninstall simulated batteries" `
                -Option "-u" -LogsPath "$LogsPath" `
                -ThrowOnError $false
            if ($err.length -ne 0)
            {
                "$err" | Log-Info
            }
        }
    }
    
    if ($DirtyModernStandby)
    {
        # Stop-Process -Id $idAmazon.Id
        Get-Process "*Outlook*" | Stop-Process -force
        Get-Process "*msedge*" | Stop-Process -force
    }

    # Enable power logs
    if ($enablepowerlogs)
    {
        "Start Power Logs" | Log-Info
        # Path for power logs
        $PowerLogsPath = join-path -path $AXEResultsPath powerlogs
        if (-not (Test-Path "$PowerLogsPath" -pathType container))
        {
            New-Item $PowerLogsPath -ItemType directory > $null
        }
        $_cmdletExist = Get-Command DisableWow64FsRedirection; if ( $_cmdletExist ) { DisableWow64FsRedirection };
        Start-PowerLogs -PowerLogsPath $PowerLogsPath
        $_cmdletExist = Get-Command RevertWow64FsRedirection ; if ( $_cmdletExist ) { RevertWow64FsRedirection };
    }
}
catch
{
    Handle-UniversalFrameworkException -Exception $_
}
finally 
{
    try
    {
        "Generating system power report..." | Log-Info
        Write-PowerConfigSystemPowerReport -ResultPath $AXEResultsPath
    }
    catch
    {
        $_ | Out-AxeError $_.Exception.Hresult
        $message = $_.Exception.Message + [Environment]::NewLine + $_.InvocationInfo.PositionMessage
        $message | Log-Info
    }

    # We should always properly dispose of this guy.
    #
    "Cleanup..." | Log-Info
    Cleanup-UniversalFramework
}

# SIG # Begin signature block
# MIIPFgYJKoZIhvcNAQcCoIIPBzCCDwMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDKZF+lvpGfhaNm
# QnseqAxngkvTsvGjFcCND6vXHrJPWqCCDBEwggV2MIIEXqADAgECAhMzAAAFdY/t
# ZZABUyRhAAEAAAV1MA0GCSqGSIb3DQEBCwUAMHkxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBUZXN0aW5nIFBD
# QSAyMDEwMB4XDTIzMDIxNjE4MzM0MloXDTI0MDUxNjE4MzM0MlowdDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEeMBwGA1UEAxMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAorUr
# gCj5FlJ+7vhjx+0mGUFTOka+WKbcrK7B95uaztftwdrnWN27Jslwy9AWtQJY3826
# OWRV4ajdLBVUB94DUgcw2heDY71cYIC7jcMwpwV6N8FHJN+OwTBzkAUWWwVarEPb
# 957z09miEYlJtASbQ8Sf61Beo2h0h82SRLPU4Q1F4CRN9WlXyn+6u5kulYIUUC0c
# bQP6qe+yukueASohANo9BRI/M6bAebYfvFookHLdybZdNFMo7sr1Bt6mCYdHPlyO
# sFYBXyZd+iQ3P6LQnjeZl9aFXXp6aFW88QawMKk/8ce2YTKAFG8y31/0IQWsAZw/
# iyhPJ9e9f9z8xdAWAQIDAQABo4IB+jCCAfYwPAYJKwYBBAGCNxUHBC8wLQYlKwYB
# BAGCNxUIg8+JTa3yAoWhnwyC+sp9geH7dIFPi/M4gp/5IgIBZAIBFTApBgkrBgEE
# AYI3FQoEHDAaMAwGCisGAQQBgjcKAxUwCgYIKwYBBQUHAwMwDgYDVR0PAQH/BAQD
# AgeAMB8GA1UdJQQYMBYGCCsGAQUFBwMDBgorBgEEAYI3CgMVMB0GA1UdDgQWBBTR
# /PEuPn+0r5mHo7syx14SmaNUSDAfBgNVHSMEGDAWgBS/ZaKrb3WjTkWWVwXPOYf0
# wBUcHDBcBgNVHR8EVTBTMFGgT6BNhktodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUZXN0aW5nJTIwUENBJTIwMjAxMCgxKS5j
# cmwwaQYIKwYBBQUHAQEEXTBbMFkGCCsGAQUFBzAChk1odHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRlc3RpbmclMjBQQ0El
# MjAyMDEwKDEpLmNydDBDBgkrBgEEAYI3FAIENh40AE0AUwBJAFQAVABlAHMAdABD
# AG8AZABlAFMAaQBnAG4AaQBuAGcAUwBoAGEAMgAtAEMAUzAMBgNVHRMBAf8EAjAA
# MA0GCSqGSIb3DQEBCwUAA4IBAQAg7Ej3KuUo0ndCL+pCb2eqn8rz77O2j90YQr2Y
# MhMsinWGq1OTp3LZfPNeI3G2BXFtvjIE++ZXjLRa/bnReVrq2p/PikV7zq0WpWzS
# gb1TBvmg80mt7Pgq/RcuNfBlO5t1wRKnmmoR3zZLHmJrXCKKSL55CyL2ZYvi+ilO
# UgcBn4E7fTGAGr41x2aKt7BhnUbiYaVwGdyYKnJv9q+6AC+fI7xnoX2mbO63zWl8
# Se9LfD7P4S/03jwAafqPiHXgkAmw4cgsK4kX9pTS/sYb336dvlilbmcAhtGf1cQ0
# /5h279IUhQb53WulhCAZ3H42KxtetiyNi8MNLoEWK9wh/hb2MIIGkzCCBHugAwIB
# AgITMwAAAC01ekaIyQdx2AAAAAAALTANBgkqhkiG9w0BAQsFADCBkDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE6MDgGA1UEAxMxTWljcm9zb2Z0
# IFRlc3RpbmcgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMDEy
# MTAyMDQzMjBaFw0zNTA2MTcyMTA0MTFaMHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xIzAhBgNVBAMTGk1pY3Jvc29mdCBUZXN0aW5nIFBDQSAy
# MDEwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvzxggau+7P/XF2Py
# pkLRE2KcsBfOukYaeyIuVXOaVLnG1NHKmP53Rw2OnfBezPhU7/LPKtRi8ak0CgTX
# xQWG8hD1TdOWCGaF2wJ9GNzieiOnmildrnkYzwxj8Br/gampQz+pC7lR8bNIOvxE
# Ll8RxVY6/8oOzYgIwf3H1fU+7+pOG3KLI71FN54fcMGnybggc+3zbD2LIQXPdxL+
# odwH6Q1beAlsMlUQR9A3yMf3+nP+RjTkVhaoN2RT1jX7w4C2jraGkaEQ1sFK9uN6
# 1BEKst4unhCX4IGuEl2IAV3MpMQoUpxg8ArmiK9L6VeK7KMPNx4p9l0h09faXQ7J
# TtuNbQIDAQABo4IB+jCCAfYwDgYDVR0PAQH/BAQDAgGGMBIGCSsGAQQBgjcVAQQF
# AgMBAAEwIwYJKwYBBAGCNxUCBBYEFOqfXzO20F+erestpsECu0A4y+e1MB0GA1Ud
# DgQWBBS/ZaKrb3WjTkWWVwXPOYf0wBUcHDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/
# BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2Nz
# L1JlcG9zaXRvcnkuaHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1Ud
# EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUowEEfjCIM+u5MZzK64V2Z/xltNEwWQYD
# VR0fBFIwUDBOoEygSoZIaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv
# cHJvZHVjdHMvTWljVGVzUm9vQ2VyQXV0XzIwMTAtMDYtMTcuY3JsMIGNBggrBgEF
# BQcBAQSBgDB+ME0GCCsGAQUFBzAChkFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpL2NlcnRzL01pY1Rlc1Jvb0NlckF1dF8yMDEwLTA2LTE3LmNydDAtBggrBgEF
# BQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNvbS9vY3NwMA0GCSqGSIb3
# DQEBCwUAA4ICAQAntNCFsp7MD6QqU3PVbdrXMQDI9v9jyPYBEbUYktrctPmvJuj8
# Snm9wWewiAN5Zc81NQVYjuKDBpb1un4SWVCb4PDVPZ0J87tGzYe9dOJ30EYGeiIa
# aStkLLmLOYAM6oInIqIwVyIk2SE/q2lGt8OvwcZevNmPkVYjk6nyJi5EdvS6ciPR
# mW9bRWRT4pWU8bZIQL938LE4lHOQAixrAQiWes5Szp2U85E0nLdaDr5w/I28J/Z1
# +4zW1Nao1prVCOqrosnoNUfVf1kvswfW3FY2l1PiAYp8sGyO57GaztXdBoEOBcDL
# edfcPra9+NLdEF36NkE0g+9dbokFY7KxhUJ8WpMiCmN4yj9LKFLvQbctGMJJY9Ew
# HFifm2pgaiaafKF1Gyz+NruJzEEgpysMo/f9AVBQ/qCdPQQGEWp3QDIaef4ts9QT
# x+RmDKCBDMTFLgFmmhbtUY0JWjLkKn7soz/LIcDUle/p5TiFD4VhfZnAcvYQHXfu
# slnyp+yuhWzASnAQNnOIO6fc1JFIwkDkcM+k/TspfAajzHooSAwXkrOWrjRDV6wI
# 0YzMVHrEyQ0hZ5NnIXbL3lrTkOPjf3NBu1naSNEaySduStDbFVjV3TXoENEnZiug
# JKYSwmhzoYHM1ngipN5rNdqJiK5ukp6E8LDzi3l5/7XctJQY3+ZgHDJosjGCAlsw
# ggJXAgEBMIGQMHkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# IzAhBgNVBAMTGk1pY3Jvc29mdCBUZXN0aW5nIFBDQSAyMDEwAhMzAAAFdY/tZZAB
# UyRhAAEAAAV1MA0GCWCGSAFlAwQCAQUAoIGcMBkGCSqGSIb3DQEJAzEMBgorBgEE
# AYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJ
# BDEiBCD9G4nBhEcG+TAlBk4XP4Tns6T190kmu6Pgb2y/JMHclTAwBgorBgEEAYI3
# AgEMMSIwIKAegBwAUwBTAEMAXABXAGkAbgBSAFQATQBwAGIAbABkMA0GCSqGSIb3
# DQEBAQUABIIBACVOh5pmKHj8Qr/IQ5MFyyiB2Nr4MUJpfrKQs8qJo0lCJSiEI22B
# Yaaje9svTh+wyD4Sce/MoN0heMgiVYWZlJx+7jBXYp/x/ki/BZfmxtlI++t1JgDz
# v+htZrKkWm/Ot92QuzvHBhIO21lJt9j7CRF/XpWtAm/+3MXkAa+/dkVG46Ddgjr0
# H51uJacpXVCWoPx14GdH2NUGxCEoDmb7dd+p0yQ0fR+h1RG/SDHTXlNQ1eA14oXU
# 4s+92VKW75MBL2LCKv0MTBpXAxD8hloyulzpOR2laEGFrCQ3PO2EIhnML8gbEb+9
# On9LAXlAN0wx+Ut/7BrBlDN3my+1XIE4j+I=
# SIG # End signature block
