JSM.Insight.psm1

#region Private functions
function New-InsightHeaders {
    param (
        [string]$InsightCreds = $InsightCreds,
        [switch]$ExperimentalApi
    )
    Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"

    $Headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
    $Headers.Add('content-type' , 'application/json')
    $Headers.Add('Authorization', 'Basic ' + $InsightCreds)

    if ($ExperimentalApi -eq $true) {
        $Headers.Add('X-ExperimentalApi', 'opt-in')
    }

    $Headers
}
#endregion

#region Public functions
function Find-InsightObject {
    [CmdletBinding()]
    param (
        [string]$IQL,
        [string]$objectTypeId,
        [int]$page = 1,
        [int]$resultsPerPage = 2000,
        [int]$orderByTypeAttrId,
        [ValidateSet(0,1)]
        [int]$asc = 1,
        [string]$objectId,
        [string]$objectSchemaId,
        [bool]$includeAttributes,
        [array]$attributesToDisplay,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {

        $RequestBody = @{
            'iql' = $iql
            'objectTypeId'   = $objectTypeId
            'resultsPerPage' = $resultsPerPage
            }
            if ($page) {
                $RequestBody.Add('page', $page)
            }
            if ($orderByTypeAttrId) {
                $RequestBody.Add('orderByTypeAttrId', $orderByTypeAttrId)
            }
            if ($asc) {
                $RequestBody.Add('asc', $asc)
            }
            if ($objectId) {
                $RequestBody.Add('objectId', $objectId)
            }
            if ($objectSchemaId) {
                $RequestBody.Add('objectSchemaId', $objectSchemaId)
            }
            if ($includeAttributes) {
                $RequestBody.Add('includeAttributes', $includeAttributes)
            }
            if ($attributesToDisplay ) {
                $RequestBody.Add('attributesToDisplay', $attributesToDisplay)
            }

        $RequestBody = $RequestBody | ConvertTo-Json -Depth 5

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/navlist/iql"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

Function Get-InsightCreds {
    [CmdletBinding()]
    [System.Diagnostics.CodeAnalysis.SuppressMessage('PSUseShouldProcessForStateChangingFunctions', '')]
    param(
        [Parameter( Mandatory )]
        [ValidateNotNullOrEmpty()]
        [Alias('user')]
        [string]$Username,
        
        [Parameter( Mandatory )]
        [ValidateNotNullOrEmpty()]
        [Alias('pass')]
        [string]$Password
    )

    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
    }

    process {
        #Encode Creds
        $auth = $username + ':' + $password
        $Encoded = [System.Text.Encoding]::UTF8.GetBytes($auth)
        $authorizationInfo = [System.Convert]::ToBase64String($Encoded)
        $Script:InsightCreds = $authorizationInfo
    }

    end {
        $authorizationInfo
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# Custom Function to Get Object Type, Attributes, and All Objects
function Get-InsightFullObjectType {
    [CmdletBinding()]
    param (
        [string]$ObjectSchemaName,
        [string]$ObjectTypeName
    )
    
    begin {
        Write-PSFMessage -Level Host -Message "Starting 'Get-InsightFullObjectType'" -Tag 'Get-InsightFullObjectType'

        $ObjectSchema = (Get-InsightObjectSchemaList).values | Where-Object { $_.name -eq $ObjectSchemaName }
        $ObjectSchemaObjectTypes = Get-InsightObjectSchemaObjectTypes -ID $ObjectSchema.id

        $JSMObjects = @()
        $objs = @()
        $page = 0

        class JSMexport {
            [string]$name
            [Object]$objectType
            [Object]$attributes
            [Object]$objects
        }
    }
    
    process {
        $e = [JSMexport]::New()
        $e.objectType = Get-InsightObjectType -ID $($ObjectSchemaObjectTypes | Where-Object { $_.name -eq $ObjectTypeName }).id
        $e.attributes = Get-InsightObjectTypeAttributes -ID $($ObjectSchemaObjectTypes | Where-Object { $_.name -eq $ObjectTypeName }).id
        #Loop through and return all objects. IncludeAttributes to get 'attributes and values' for the objects themselves
        do {
            $page++
            Write-PSFMessage -Level Host -Message "Preforming 'Find-InsightObject' on page: $page" -Tag 'Get-InsightFullObjectType'
            $results = Find-InsightObject -objectSchemaId $ObjectSchema.id -objectTypeId $e.objectType.id -resultsPerPage 2000 -page $page -IQL ${objectType = "$ObjectTypeName"} -includeAttributes $true
            $objs += $results.objectEntries
        } until ( ( $page -eq $results.pageSize ) -or ( $results.pageSize -eq 0 ) )
        $e.objects = $objs
        $e.name = $e.objectType.name
        $JSMObjects += $e
    }
    
    end {
        Write-PSFMessage -Level Host -Message "Completed 'Get-InsightFullObjectType'" -Tag 'Get-InsightFullObjectType'
        $JSMObjects
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-icon/#api-icon-id-get
function Get-InsightIcon {
    [CmdletBinding()]
    param (
        [String]$Version = "1",
        [string]$IconID = "global",
        [switch]$Full,
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        # Default is Global which will show all icons.
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/icon/$IconID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        if ($Full -eq $true) {
            $response
        }
        else {
            $response | Select id,name
        }

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-object/#api-object-id-get
function Get-InsightObject {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-object/#api-object-id-attributes-get
function Get-InsightObjectAttributes {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id/attributes"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-icon/#api-icon-id-get
function Get-InsightObjectByIQL {
    [CmdletBinding()]
    param (
        [String]$Version = "1",
        [string]$IQL,
        [int]$page,
        [int]$resultsPerPage = 25,
        [bool]$includeAttributes,
        [int]$includeAttributesDeep = 1,
        [bool]$includeTypeAttributes,
        [bool]$includeExtendedInfo,
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        $RequestBody = @{
            'resultsPerPage' = $resultsPerPage
            }
        if ($IQL) {
            $RequestBody.Add("iql",$iql )
        }
        if ($page) {
            $RequestBody.Add("page",$page )
        }
        if ($includeAttributes) {
            $RequestBody.Add("includeAttributes",$includeAttributes )
        }
        if ($includeAttributesDeep) {
            $RequestBody.Add("includeAttributesDeep",$includeAttributesDeep )
        }
        if ($includeTypeAttributes) {
            $RequestBody.Add("includeTypeAttributes",$includeTypeAttributes )
        }
        if ($includeExtendedInfo) {
            $RequestBody.Add("includeExtendedInfo",$includeExtendedInfo )
        }
        
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
        Write-Verbose $RequestBody
    }
    
    process {
        # Default is Global which will show all icons.
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/iql/objects"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-objectconnectedtickets/#api-objectconnectedtickets-objectid-tickets-get
function Get-InsightObjectConnectedTickets {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectconnectedtickets/$id/tickets"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-object/#api-object-id-history-get
function Get-InsightObjectHistory {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id/history"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-object/#api-object-id-referenceinfo-get
function Get-InsightObjectReferenceInfo {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id/referenceinfo"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-objectschema/#api-objectschema-id-get
function Get-InsightObjectSchema {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = '1',
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Get-InsightObjectSchemaAttributes {
    [CmdletBinding()]
    param (
        [string]$ID,
        [bool]$onlyValueEditable = $False,
        [bool]$extended = $False,
        [string]$Query,
        [String]$Version = '1',
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $RequestBody = @{
            }
            if ($onlyValueEditable) {
                $RequestBody.Add('onlyValueEditable',$onlyValueEditable)
            }
            if ($extended) {
                $RequestBody.Add('extended',$extended)
            }
            if ($Query) {
                $RequestBody.Add('query',$Query)
            }
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/$id/attributes"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Get-InsightObjectSchemaList {
    [CmdletBinding()]
    param (
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/list"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Get-InsightObjectSchemaObjectTypes {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = '1',
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/$id/objecttypes/flat"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Get-InsightObjectType {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}



# API Docs need info on how to add Query parameters.
# https://developer.atlassian.com/cloud/insight/rest/api-group-objecttype/#api-objecttype-id-attributes-get

function Get-InsightObjectTypeAttributes {
    [CmdletBinding()]
    param (
        [string]$ID,
        [switch]$onlyValueEditable,
        [switch]$orderByName,
        [string]$query,
        [switch]$includeValuesExist,
        [switch]$excludeParentAttributes,
        [switch]$includeChildren,
        [switch]$orderByRequired,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )

    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/$id/attributes"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

#https://developer.atlassian.com/cloud/insight/rest/api-group-progress/#api-progress-category-imports-id-get
function Get-InsightProgressCatagoryImports {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/progress/category/imports/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-config/#api-config-statustype-get
function Get-InsightStatusTypeByID {
    [CmdletBinding()]
    param (
        [String]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype/$ID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-config/#api-config-statustype-get
function Get-InsightStatusTypes {
    [CmdletBinding()]
    param (
        [string]$objectSchemaId,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        if ($objectSchemaId) {
            $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype/?objectSchemaId=$objectSchemaId"
        }
        else {
            $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype/"
        }
    }
    
    end {
        Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET
    }
}


function Get-InsightWorkspaceID {
    [CmdletBinding()]
    param (
        [string]$InsightServerUrl,
        [string]$InsightCreds = $InsightCreds
    )

    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders -ExperimentalApi
    }
    
    process {
        $Request = [System.UriBuilder]"$InsightServerUrl/rest/servicedeskapi/insight/workspace"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method GET

            $script:InsightWorkspaceID = $response.values.workspaceId
            $response.values.workspaceId
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
        } 
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

function New-InsightAttributeArray {
    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [Parameter(Mandatory = $true,valuefrompipelinebypropertyname = $true)]
        [int]$AttributeId,

        [ValidateNotNullOrEmpty()]
        [Parameter(Mandatory = $true,valuefrompipelinebypropertyname = $true)]
        [String[]]$AttributeValues
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"

        $values = New-Object System.Collections.ArrayList 
    }
    
    process {
        $AttributeValues | ForEach-Object {
            $values.Add(@{'value' = $_}) | Out-Null
        }        
        $Attribute = @{
            'objectTypeAttributeId' = $AttributeId
            'objectAttributeValues'   = @($values)
            }
    }

    end {
        Write-Output $Attribute
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
        }
}



function New-InsightObject {
    [CmdletBinding()]
    param (
        [string]$objectTypeId,
        [array]$attributesArray,
        [Bool]$hasAvatar,
        [string]$avatarUUID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {

        $RequestBody = @{
            'objectTypeId' = $objectTypeId
            'attributes'   = @($attributesArray)
            }

        $RequestBody = $RequestBody | ConvertTo-Json -Depth 5

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/create"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function New-InsightObjectSchema {
    [CmdletBinding()]
    param (
        [string]$Name,
        [string]$objectSchemaKey,
        [string]$Description,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $RequestBody = @{
            'name' = $Name
            'objectSchemaKey'   = $objectSchemaKey
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/create"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function New-InsightObjectType {
    [CmdletBinding()]
    param (
        [string]$name,
        [string]$description,
        [string]$iconID,
        [string]$ObjectSchemaID,
        [string]$ParentObjectTypeID,
        [bool]$Inherited,
        [bool]$AbstractObjectType,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"

        $Headers = New-InsightHeaders

        $RequestBody = @{
            'name' = $Name
            'iconId'   = $iconID
            'objectSchemaId'   = $objectSchemaId
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($parentObjectTypeId) {
                $RequestBody.Add('parentObjectTypeId', $parentObjectTypeId)
            }
            if ($Inherited -eq $true) {
                $RequestBody.Add('inherited', $Inherited)
            }
            if ($AbstractObjectType -eq $true) {
                $RequestBody.Add('abstractObjectType', $AbstractObjectType)
            }

        $RequestBody = ConvertTo-Json $RequestBody -Depth 1

    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/create"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function New-InsightObjectTypeAttribute {
    [CmdletBinding()]
    param (
        [string]$ObjectTypeId,
        [string]$Name,
        [string]$Label,
        [string]$Description,
        [ValidateSet("Default","Object Reference","User","Group","Status")]
        [string]$Type,
        [ValidateSet("None","Text","Integer","Boolean","Double","Date","Time","DateTime","URL","Email","TextArea","Select","IP Address")]
        [string]$defaultTypeId,
        [string]$typeValue,
        [array]$typeValueMulti,
        [string]$additionalValue,
        [int]$minimumCardinality,
        [int]$maximumCardinality,
        [string]$suffix,
        [bool]$includeChildObjectTypes,
        [bool]$hidden,
        [bool]$uniqueAttribute,
        [bool]$summable,
        [string]$regexValidation,
        [string]$iql,
        [string]$options,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        $ConvertedTypeID = switch ($Type) {
            "Default" { 0 }
            "Object Reference" { 1 }
            "User" { 2 }
            "Group" { 4 }
            "Status" { 7 }
        }

        $ConvertedDefaultTypeID = switch ($defaultTypeId) {
            "None" { -1 }
            "Text" { 0 }
            "Integer" { 1 }
            "Boolean" { 2 }
            "Double" { 3 }
            "Date" { 4 }
            "Time" { 5 }
            "DateTime" { 6 }
            "URL" { 7 }
            "Email" { 8 }
            "TextArea" { 9 }
            "Select" { 10 }
            "IP Address" { 11 }
        }


        $RequestBody = @{
            'name' = $Name
            'type'   = $ConvertedTypeID
            }
            if ($Label) {
                $RequestBody.Add('label', [System.Convert]::ToBoolean($Label) )
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($defaultTypeId) {
                $RequestBody.Add('defaultTypeId', $ConvertedDefaultTypeID)
            }
            if ($typeValue) {
                $RequestBody.Add('typeValue', $typeValue)
            }
            if ($typeValueMulti) {
                $RequestBody.Add('typeValueMulti', $typeValueMulti)
            }
            if ($additionalValue) {
                $RequestBody.Add('additionalValue', $additionalValue)
            }
            if ($minimumCardinality) {
                $RequestBody.Add('minimumCardinality', $minimumCardinality)
            }
            if ($maximumCardinality) {
                $RequestBody.Add('maximumCardinality', $maximumCardinality)
            }
            if ($suffix) {
                $RequestBody.Add('suffix', $suffix)
            }
            if ($includeChildObjectTypes  -eq $true) {
                $RequestBody.Add('includeChildObjectTypes', [System.Convert]::ToBoolean($includeChildObjectTypes) )
            }
            if ($hidden -eq $true) {
                $RequestBody.Add('hidden', [System.Convert]::ToBoolean($hidden) )
            }
            if ($uniqueAttribute -eq $true) {
                $RequestBody.Add('uniqueAttribute', [System.Convert]::ToBoolean($uniqueAttribute) )
            }
            if ($summable -eq $true) {
                $RequestBody.Add('summable', [System.Convert]::ToBoolean($summable) )
            }
            if ($regexValidation) {
                $RequestBody.Add('regexValidation', $regexValidation)
            }
            if ($iql) {
                $RequestBody.Add('iql', $iql)
            }
            if ($options) {
                $RequestBody.Add('options', $options)
            }

        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
        $RequestBody
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttypeattribute/$ObjectTypeId"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-config/#api-config-statustype-post
function New-InsightStatusType {
    [CmdletBinding()]
    param (
        [String]$Name,
        [String]$Description,
        [ValidateSet("InActive\Red","Active\Green","Pending\Yellow")]
        [String]$Category,
        [String]$objectSchemaId,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        switch ($Category) {
            "InActive\Red" { $CategoryID = 0 }
            "Active\Green" { $CategoryID = 1 }
            "Pending\Yellow" { $CategoryID = 2 }
        }

        $RequestBody = @{
            'name' = $Name
            'category'   = $CategoryID
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($objectSchemaId) {
                $RequestBody.Add('objectSchemaId', $objectSchemaId)
            }
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Remove-InsightObject {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method DELETE
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Remove-InsightObjectSchema {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = '1',
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method DELETE
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Remove-InsightObjectType {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method DELETE
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Remove-InsightObjectTypeAttribute {
    [CmdletBinding()]
    param (
        [string]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttypeattribute/$ID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method DELETE
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-config/#api-config-statustype-get
function Remove-InsightStatusType {
    [CmdletBinding()]
    param (
        [String]$ID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype/$ID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method DELETE
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Set-InsightObject {
    [CmdletBinding()]
    param (
        [string]$ID,
        [string]$objectTypeId,
        [array]$attributesArray,
        [Bool]$hasAvatar,
        [string]$avatarUUID,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {

        $RequestBody = @{
            'objectTypeId' = $objectTypeId
            'attributes'   = @($attributesArray)
            }

        $RequestBody = $RequestBody | ConvertTo-Json -Depth 5

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/object/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method PUT
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Set-InsightObjectPosition {
    [CmdletBinding()]
    param (
        [string]$ID,
        [string]$toObjectTypeId,
        [int]$position,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {

        $RequestBody = @{
            'position' = $position
            }
            if ($toObjectTypeId) {
                $RequestBody.Add('toObjectTypeId', $toObjectTypeId)
            }

        $RequestBody = ConvertTo-Json $RequestBody -Depth 1

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/$id/position"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Set-InsightObjectSchema {
    [CmdletBinding()]
    param (
        [string]$ID,
        [string]$Name,
        [string]$objectSchemaKey,
        [string]$Description,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders
    }
    
    process {
        $RequestBody = @{
            'name' = $Name
            'objectSchemaKey'   = $objectSchemaKey
            }
            if ($Description) {
                $RequestBody.Add('description',$Description)
            }
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1

        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objectschema/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method POST
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response
        
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Set-InsightObjectType {
    [CmdletBinding()]
    param (
        [string]$ID,
        [string]$name,
        [string]$description,
        [string]$iconID,
        [string]$ObjectSchemaID,
        [string]$ParentObjectTypeID,
        [bool]$Inherited,
        [string]$AbstractObjectType,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        $RequestBody = @{
            'name' = $Name
            'iconID'   = $iconID
            'objectSchemaId'   = $objectSchemaId
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($parentObjectTypeId) {
                $RequestBody.Add('parentObjectTypeId', $parentObjectTypeId)
            }
            if ($Inherited) {
                $RequestBody.Add('inherited', $Inherited)
            }
            if ($AbstractObjectType) {
                $RequestBody.Add('abstractObjectType', $AbstractObjectType)
            }

        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttype/$id"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Headers $headers -Method PUT
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}


function Set-InsightObjectTypeAttribute {
    [CmdletBinding()]
    param (
        [string]$ID,
        [string]$ObjectTypeId,
        [string]$Name,
        [string]$Label,
        [string]$Description,
        [ValidateSet("Default","Object Reference","User","Group","Status")]
        [string]$Type,
        [ValidateSet("None","Text","Integer","Boolean","Double","Date","Time","DateTime","URL","Email","TextArea","Select","IP Address")]
        [string]$defaultTypeId,
        [string]$typeValue,
        [array]$typeValueMulti,
        [string]$additionalValue,
        [int]$minimumCardinality,
        [int]$maximumCardinality,
        [string]$suffix,
        [bool]$includeChildObjectTypes,
        [bool]$hidden,
        [bool]$uniqueAttribute,
        [bool]$summable,
        [string]$regexValidation,
        [string]$iql,
        [string]$options,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        $ConvertedType = switch ($Type) {
            "Default" { 0 }
            "Object Reference" { 1 }
            "User" { 2 }
            "Group" { 4 }
            "Status" { 7 }
        }

        $ConvertedTypeID = switch ($defaultTypeId) {
            "None" { -1 }
            "Text" { 0 }
            "Integer" { 1 }
            "Boolean" { 2 }
            "Double" { 3 }
            "Date" { 4 }
            "Time" { 5 }
            "DateTime" { 6 }
            "URL" { 7 }
            "Email" { 8 }
            "TextArea" { 9 }
            "Select" { 10 }
            "IP Address" { 11 }
        }


        $RequestBody = @{
            'name' = $Name
            'type'   = $ConvertedType
            }
            if ($Label) {
                $RequestBody.Add('label', $Label)
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($ConvertedTypeID) {
                $RequestBody.Add('defaultTypeId', $ConvertedTypeID)
            }
            if ($typeValue) {
                $RequestBody.Add('typeValue', $typeValue)
            }
            if ($typeValueMulti) {
                $RequestBody.Add('typeValueMulti', $typeValueMulti)
            }
            if ($additionalValue) {
                $RequestBody.Add('additionalValue', $additionalValue)
            }
            if ($minimumCardinality) {
                $RequestBody.Add('minimumCardinality', $minimumCardinality)
            }
            if ($maximumCardinality) {
                $RequestBody.Add('maximumCardinality', $maximumCardinality)
            }
            if ($suffix) {
                $RequestBody.Add('suffix', $suffix)
            }
            if ($includeChildObjectTypes  -eq $true) {
                $RequestBody.Add('includeChildObjectTypes', $includeChildObjectTypes)
            }
            if ($hidden -eq $true) {
                $RequestBody.Add('hidden', $hidden)
            }
            if ($uniqueAttribute -eq $true) {
                $RequestBody.Add('uniqueAttribute', $uniqueAttribute)
            }
            if ($summable -eq $true) {
                $RequestBody.Add('summable', $summable)
            }
            if ($regexValidation) {
                $RequestBody.Add('regexValidation', $regexValidation)
            }
            if ($iql) {
                $RequestBody.Add('iql', $iql)
            }
            if ($options) {
                $RequestBody.Add('options', $options)
            }

        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/objecttypeattribute/$ObjectTypeId/$ID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -body $RequestBody -Headers $headers -Method PUT
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}

# https://developer.atlassian.com/cloud/insight/rest/api-group-config/#api-config-statustype-id-put
function Set-InsightStatusType {
    [CmdletBinding()]
    param (
        [String]$ID,
        [String]$Name,
        [String]$Description,
        [ValidateSet("InActive\Red","Active\Green","Pending\Yellow")]
        [String]$Category,
        [String]$objectSchemaId,
        [String]$Version = "1",
        [string]$InsightCreds = $InsightCreds,
        [string]$InsightWorkspaceID = $InsightWorkspaceID
    )
    
    begin {
        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
        $Headers = New-InsightHeaders

        switch ($Category) {
            "InActive\Red" { $CategoryID = 0 }
            "Active\Green" { $CategoryID = 1 }
            "Pending\Yellow" { $CategoryID = 2 }
        }

        $RequestBody = @{
            'name' = $Name
            'category'   = $CategoryID
            }
            if ($Description) {
                $RequestBody.Add('description', $Description)
            }
            if ($objectSchemaId) {
                $RequestBody.Add('objectSchemaId', $objectSchemaId)
            }
        $RequestBody = ConvertTo-Json $RequestBody -Depth 1
    }
    
    process {
        $Request = [System.UriBuilder]"https://api.atlassian.com/jsm/insight/workspace/$InsightWorkspaceID/v$Version/config/statustype/$ID"
    }
    
    end {
        try {
            $response = Invoke-RestMethod -Uri $Request.Uri -Body $RequestBody -Headers $headers -Method PUT
        }
        catch {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Failed"
            Write-Error -Message "$($_.Exception.Message)" -ErrorId $_.Exception.Code -Category InvalidOperation
        } 

        $response

        Write-Verbose "[$($MyInvocation.MyCommand.Name)] Complete"
    }
}
#endregion