Private/Common/Invoke-ABRestMethod.ps1


function Invoke-ABRestMethod {
    [CmdletBinding(SupportsShouldProcess)]
    
    param (
        [Parameter(Mandatory = $true)] [ValidateSet('get', 'set', 'patch', 'post', 'delete')] $method, 
        [Parameter(Mandatory = $true)] [ValidateScript ( { Test-ABUri -address $_ })]$uri,
        [Parameter(Mandatory = $false )] $body,
        [Parameter(Mandatory = $false )] $contentType = "application/json",
        [Parameter(Mandatory = $false )] [hashtable] $Headers,
        [switch] $Force,
        [switch] $FinalTry
    )
    
    begin {
        if (-not $PSBoundParameters.ContainsKey('Verbose')) {
            $VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference')
        }
        if (-not $PSBoundParameters.ContainsKey('Confirm')) {
            $ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
        }
        if (-not $PSBoundParameters.ContainsKey('WhatIf')) {
            $WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
        }
    }
    
    process {
        Write-Verbose "method: $method"
        Write-Verbose "contentType: $contentType"
        
        # If (!$A.isValid -and $uri -notmatch "login") {
        # throw "No valid session"
        # }
        
        if (!$Headers) { $Headers = @{ } } 
        If (!$Headers.Authorization -and $uri -notmatch "login") { $Headers.Authorization = "Bearer $($_ABSession.Token)" }

        Write-Verbose (ConvertTo-Json $Headers)

        
        if ($contentType -match "json" -and $body -is [hashtable]) {
            $body = ConvertTo-Json $body -Compress -Depth 10
        }
        if ($body) { Write-Verbose "body:$($body)" }


        if ($Force -or $PSCmdlet.ShouldProcess("$uri")) {

            $request = [System.Net.HttpWebRequest]::Create($uri)

            $request.Method = $method

            if ($_ABSession.Cookies.Count -gt 0) {
                $request.CookieContainer = $_ABSession.Cookies
            }
            
            foreach ($Key in $Headers.Keys | Where-Object { $_ -notin @("host", "accept") }) {
                $request.Headers.Add($key, $Headers.$Key)
            } 
            if ($Headers.Host) {
                $request.Host = $Headers.Host
            }
            if ($Headers.Accept) {
                $request.Accept = $Headers.Accept
            }
            $request.ContentType = $contentType
            $request.Timeout = 10000;
            
            if ($AB_Session.Proxy) {
                $request.Proxy = [System.Net.WebProxy]::new($_ABSession.Proxy)
                $request.Proxy.Credentials = $_ABSession.ProxyCredential
            }

            if ($body) {
                #Build the requestbody
                $Bytes = [System.Text.Encoding]::Default.GetBytes($body)
                $request.ContentLength = $Bytes.Length
                $Stream = $request.GetRequestStream()
                $Stream.Write($Bytes, 0, $Bytes.Length);
                
                $Stream.Flush();
                $Stream.Close();
            }
        
            try {
                $Response = $request.GetResponse()

                if ($Response.Headers -contains 'Set-Cookie') {

                    $cookies = ($Response.Headers.Get("Set-Cookie")) -split ","
                    foreach ($cookie in $cookies) {
                        $cookieParts = $cookie.Trim() -split ";"
                        $cookieNameValue = $cookieParts[0].Trim() -split "="
                        $cookieName = $cookieNameValue[0].Trim()
                        $cookieValue = $cookieNameValue[1].Trim()

                        $newCookie = New-Object System.Net.Cookie
                        $newCookie.Name = $cookieName
                        $newCookie.Value = $cookieValue

                        foreach ($part in $cookieParts[1..($cookieParts.Count - 1)]) {
                            $part = $part.Trim()
                            if ($part -like "Path=*") {
                                $newCookie.Path = $part.Substring(5)
                            }
                            elseif ($part -eq "Secure") {
                                $newCookie.Secure = $true
                            }
                            
                        }
                        
                        $newCookie.Domain = ([uri]$_ABSession.Uri).host# Replace with the appropriate domain
                        $_ABSession.Cookies.Add($newCookie)
                    }


                }

                $ResponseStream = $Response.GetResponseStream()
                $SteamReader = New-Object System.IO.StreamReader($ResponseStream)
                

    
                $ResponseObject = @{
                    BaseResponse = $Response
                    Content      = $SteamReader.ReadToEnd() 
                    Request      = $request
                    Session      = $_ABSession
                }
            }
            catch [System.Net.WebException] {
                $ResponseObject = @{
                    BaseResponse = $_.Exception.response
                    Content      = $_.Exception.Message
                    Request      = $request
                    Session      = $_ABSession
                }
            }
            
            $Global:res = $ResponseObject

            #ConvertTo-Json $responseObject -Depth 5 | Out-File "$PSScriptRoot\..\..\log\Request.json"
        }

        Switch ($ResponseObject.BaseResponse.StatusCode.Value__) {
            <#
                    200 OK
                    201 Created
                    202 Accepted
                    203 Non-Authoritative Information
                    204 No Content
                #>

            { $_ -in @(200, 201, 202, 203, 204) } {
                if ($ResponseObject.Content) {
                    Return ConvertFrom-Json $ResponseObject.Content
                }
                else {
                    return @{ }
                }
            }
            { $_ -in @(400) } {
                throw [System.InvalidOperationException]::new("$($responseObject.BaseResponse.StatusCode.Value__):: $($ResponseObject.Content)")
            }
            { $_ -in @(401) } {
                throw [System.InvalidOperationException]::new("$($responseObject.BaseResponse.StatusCode.Value__):: $($ResponseObject.Content)")
            }
            { $_ -in @(403) } {
                throw [System.InvalidOperationException]::new("$($responseObject.BaseResponse.StatusCode.Value__):: $($ResponseObject.Content)")
            }
            { $_ -in @(404) } {
                throw [System.InvalidOperationException]::new("$($responseObject.BaseResponse.StatusCode.Value__):: $($ResponseObject.Content)")
            }
            default {
                #ConvertTo-Json $responseObject -Depth 5 | Out-File "$PSScriptRoot\..\..\log\Error.json"
                throw [System.InvalidOperationException]::new("$($responseObject.BaseResponse.StatusCode.Value__):: $($ResponseObject.Content)")
            }
        }
        $Global:res = $ResponseObject
    }

    
    end {
    }
}