<#
    .SYNOPSIS
    Calculates Power Consumption data from the PDU controller.

    .DESCRIPTION
    Calculates Power Consumption data.

    .PARAMETER ReadPower
    String, executable to get the power data.

    .PARAMETER Stage
    String, execution stage. Either pre stage (run before all assessments) or post stage (run after all assessments).

    .PARAMETER IP
    String, PI address of the PDU controller.

    .PARAMETER Username
    String, user name of the PDU controller.

    .PARAMETER Password
    String, user password of the PDU controller.

    .PARAMETER Outlet
    Integer, Outlet of the controller.

    .EXAMPLE
    ReadRaritanPower.ps1 -ReadPower 'Python #%AssessmentAxeUniversalPath%\ReadRaritanPower.py#'
                         -Stage Pre
                         -Config "%AssessmentAxeUniversalPath%\ReadRaritanPower.config.json"
#>

Param(
    [AllowEmptyString()]
    [parameter(Mandatory = $true)]
    [string]
    $ReadPower = "",

    [parameter(Mandatory = $true)]
    [string]
    $Stage = ""
)

# Exit $exitCode will not affect the real return code but it will affect return code 0 ($exitCode == 0) or 1 ($exitCode != 0) no matter run by powershell.exe -Command or -File.
$exitCode = 0
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

New-Variable -Name AcPowerXml -Value "AcPower.Xml" -Option Constant
New-Variable -Name AcPowerErr -Value "AcPowerErr.txt" -Option Constant

try
{
    # If we are not interested in AC energy test, we should end this script as soon as possible.
    $jobSettings = (Get-Content -Path "C:\Data\test\bin\adk\job.settings.json" | ConvertFrom-Json)
    if (-not $jobSettings.EnableAcTest)
    {
        return
    }

    #*****************************************************************
    #
    #                Definitions and imports
    #
    #*****************************************************************

    #set to true if you need to hang the script at the end to check console output
    $Global:debugFlag = $false

    # Tools and resources
    $Global:AxeUniversalPath = Convert-Path((Get-Item env:\AssessmentAxeUniversalPath -ErrorAction Stop).value)
    $Global:InvocationPath   = Split-Path -Path $MyInvocation.MyCommand.Path -Parent

    try
    {
        # Import the modules and functions
        Import-Module "$AxeUniversalPath\UniversalAssessment.psm1" -ErrorAction Stop
    }
    catch
    {
        $exitCode = 100
        throw "[Job][User?ExecuteWorkload]Failed to import $AxeUniversalPath\UniversalAssessment.psm1"
    }

    Initialize-UniversalFramework -InvocationPath $InvocationPath -AxeUniversalPath $AxeUniversalPath

    $Config = (Join-Path -Path ($Global:AxeUniversalPath) "ReadRaritanPower.config.json")
    $configPdu = (Get-Content -Path "$Config" | ConvertFrom-Json)

    $fullPathAcPowerXml = "$($Global:EnergyPersistentResultsFolder)\$AcPowerXml"
    $fullPathAcPowerErr = "$AXEResultsPath\$Stage$AcPowerErr"

    if (!$ReadPower)
    { # There is no ReadPower command! Please input power data manually.
        $configPdu.ManuallyEnterEnergyValue = $true
    }

    if (-not (Test-Path $fullPathAcPowerXml))
    {
        "<root></root>" > $fullPathAcPowerXml
    }
    $AcPowerXmlDoc = [xml](Get-Content -Path $fullPathAcPowerXml)

    if ($Stage -ieq "Pre")
    {
        if (-not $configPdu.ManuallyEnterEnergyValue)
        {
            # list all fields in config.json and there should be no empty string in these fields
            $configFields = @( "IP", "Username", "Password", "Outlet", "PythonId", "RaritanPduRpcSdkUrl", "ManuallyEnterEnergyValue" )
            foreach ($field in $configFields)
            {
                if (!($configPdu.PSobject.Properties.name -match $field))
                {
                    throw "Missing field:$field in $Config"
                }
                if ($($configPdu."$field") -is [string])
                {
                    if (!$($configPdu."$field"))
                    {
                        throw "Invalid value of $field in $Config"
                    }
                }
            }
            [ipaddress]$($configPdu.IP)

            if ($configPdu.Outlet -lt 0)
            {
                [int]$configPdu.Outlet = Read-Host "`nIP:$($configPdu.IP) Username:$($configPdu.Username) Password:$($configPdu.Password)`nWhat is the Outlet number? "
            }
        }
    }
    else
    {
        if ($configPdu.Outlet -lt 0)
        {
            # We only ask Outlet in Pre Stage.
            [int]$configPdu.Outlet = $AcPowerXmlDoc.DocumentElement.Outlet
        }
    }

    $LastExitCode = 0
    if ($configPdu.ManuallyEnterEnergyValue)
    {
        if ($Stage -ieq "Pre")
        {
            [double]$activeEnergy = Read-Host "`n`nInput power data at start (mWh)? "
        }
        elseif ($Stage -ieq "Post")
        {
            [double]$activeEnergy = Read-Host "`n`nInput power data at end (mWh)? "
        }
        $CurrentPowerResult = "{ 'ActiveEnergy': $activeEnergy }" 2> $fullPathAcPowerErr
    }
    else
    {
        [string]$cmdReadPower = ($ReadPower, $configPdu.IP, $configPdu.Username, $configPdu.Password, $configPdu.Outlet)
        $CurrentPowerResult = (Invoke-Expression $cmdReadPower 2> $fullPathPowerErr)
    }

    $lxc = $LastExitCode
    $CurrentPower = ($CurrentPowerResult | ConvertFrom-Json)
    if ($CurrentPower.Log)
    {
        "[$($Global:AxeAsmtName)][$($Global:AxeAsmtExecuteWorkloadTag)]ReadPower Log:`n$($CurrentPower.Log)" | Log-Info
    }

    if ($CurrentPower.Exception)
    {
        $exitCode = 101
        throw $CurrentPower.Exception
    }

    if ($lxc -ne 0)
    {
        if ((Get-Item $fullPathAcPowerErr).length -gt 0)
        {
            $exitCode = 102
            throw "[$($Global:AxeAsmtName)][$($Global:AxeAsmtExecuteWorkloadTag)]" + (Get-Content $fullPathAcPowerErr)
        }
        else
        {
            throw "[$($Global:AxeAsmtName)][$($Global:AxeAsmtExecuteWorkloadTag)]ReadPower LastExitCode:$lxc"
        }
    }

    if ($Stage -ieq "Pre")
    {
        # We will not create Outlet node for the second workload, all workloads share one Outlet.
        if ($AcPowerXmlDoc.DocumentElement.Outlet -eq $null)
        {
            # handle Outlet
            [Xml.XmlText]$OutletValue = $AcPowerXmlDoc.CreateTextNode("$($configPdu.Outlet)")

            [Xml.XmlElement]$Outlet = $AcPowerXmlDoc.CreateElement("Outlet")
            $Outlet.AppendChild($OutletValue)

            # add Outlet as a child of root
            $AcPowerXmlDoc.DocumentElement.AppendChild($Outlet)
        }

        # handle the current ActiveEnergy
        [Xml.XmlText]$ActiveEnergyValue = $AcPowerXmlDoc.CreateTextNode("$($CurrentPower.ActiveEnergy)")

        [Xml.XmlElement]$ActiveEnergy = $AcPowerXmlDoc.CreateElement("ActiveEnergy")
        $ActiveEnergy.AppendChild($ActiveEnergyValue)

        # add $ActiveEnergy as a child of $Pre
        [Xml.XmlElement]$Pre = $AcPowerXmlDoc.CreateElement("Pre")
        $Pre.AppendChild($ActiveEnergy)

        # add $Pre as a child of $Wrkload (Asmt-EdgeAutomationWorkload-0...)
        [Xml.XmlElement]$Workload = $AcPowerXmlDoc.CreateElement("$($Global:AxeAsmtName)")
        $Workload.AppendChild($Pre)

        # add $Workload (Asmt-EdgeAutomationWorkload-0...) as a child of root
        $AcPowerXmlDoc.DocumentElement.AppendChild($Workload)
        $AcPowerXmlDoc.Save($fullPathAcPowerXml)
    }
    elseif ($Stage -ieq "Post")
    {
        # handle the current ActiveEnergy
        [Xml.XmlText]$ActiveEnergyValue = $AcPowerXmlDoc.CreateTextNode("$($CurrentPower.ActiveEnergy)")

        [Xml.XmlElement]$ActiveEnergy = $AcPowerXmlDoc.CreateElement("ActiveEnergy")
        $ActiveEnergy.AppendChild($ActiveEnergyValue)

        # add $ActiveEnergy as a child of $Post
        [Xml.XmlElement]$Post = $AcPowerXmlDoc.CreateElement("Post")
        $Post.AppendChild($ActiveEnergy)

        # add $Post as a child of $Wrkload (Asmt-EdgeAutomationWorkload-0...)
        [Xml.XmlElement]$Workload = $AcPowerXmlDoc.DocumentElement."$($Global:AxeAsmtName)"
        $Workload.AppendChild($Post)

        $AcPowerXmlDoc.Save($fullPathAcPowerXml)
    }
    else
    {
        $exitCode = 103
        throw "[$($Global:AxeAsmtName)][$($Global:AxeAsmtExecuteWorkloadTag)]Invalid input parameter Stage:$Stage."
    }
}
catch
{
    Handle-UniversalFrameworkException -Exception $_
}
finally
{
    Cleanup-UniversalFramework
    Exit $exitCode
}

# SIG # Begin signature block
# MIIPFgYJKoZIhvcNAQcCoIIPBzCCDwMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC26MyBRZ+tEPcj
# 9qpCax4spof1EiVEgorlkqte2HfWwKCCDBEwggV2MIIEXqADAgECAhMzAAAFdY/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
# BDEiBCABHF2TWyqX6gpAJfRmYV8L/GqV0RHN+sGtJNxUJnlbRTAwBgorBgEEAYI3
# AgEMMSIwIKAegBwAUwBTAEMAXABXAGkAbgBSAFQATQBwAGIAbABkMA0GCSqGSIb3
# DQEBAQUABIIBADG6UcpIfu1DS1672kXUC1BpPDRcQjPpas9OZk5br4WlLBNewmIf
# 9ELbH8jdl4q5fKAB8bpaq3a0BXXQkJ0IxBKgoBQVGTPcCTrbdexCZ1ZCwgS+f2pF
# QEEan7txCl5ZPVIHaCAq5HkVHjfl4pisiXwLEKW4QCELc0OwPwiVLlCyP/+VoEAZ
# yu91YCq4vI9vQP2jMdV7SgYFT2ciRaHMKSsvBtFXVK6L22+/XCggqcg2LllxKtes
# EvH+W6ky0TvWFyuaN87jy32M2rzcZJOi2R31qa8puRYXc0Urg+hwUiNKcT6PkbJH
# rYzd7ulShkgMKhHRzlEtjXyX8MeugeLs+zY=
# SIG # End signature block
