Public/GeneratedValues/Get-JIMGeneratedValueDecision.ps1

# Copyright (c) Tetron Limited. All rights reserved.
# Licensed under the Tetron Commercial License. See LICENSE file in the project root.

function Get-JIMGeneratedValueDecision {
    <#
    .SYNOPSIS
        Gets generated values held for a decision: values a target rejected as already in use that JIM did not
        correct (Unique Value Generation, Collision Remediation).
 
    .DESCRIPTION
        When a Connected System rejects a generated value as already in use, Collision Remediation normally chooses
        the next free value and exports it again. It holds the export for a decision instead when correcting the
        value would rename an account another Connected System has already accepted (AnchoredElsewhere), when JIM
        cannot tell whether one has because its Connector Space was cleared and not fully imported since
        (CannotTell), when the value has been corrected as often as JIM allows (RemediationLimitReached), or when no
        other value could be generated (NoValueAvailable). The export stays held until someone allows the rename
        (Approve-JIMGeneratedValueRename), tries again (Reset-JIMGeneratedValueDecision), or changes the Attribute
        Flow.
 
        A list holds two statuses: NeedsDecision (held until someone acts) and RenameAllowed (a rename has been
        allowed and the next export run will choose the next free value). Values JIM corrected need no action and
        are not listed; -Summary counts them.
 
    .PARAMETER ConnectedSystemId
        Restrict to values involving one Connected System: it rejected the value, it anchors the value, or the value
        is exported to and checked in it.
 
    .PARAMETER SyncRuleId
        Restrict to values generated by Attribute Flows on one Synchronisation Rule.
 
    .PARAMETER Status
        Restrict to NeedsDecision or RenameAllowed. Omit for both.
 
    .PARAMETER MetaverseObjectId
        Restrict to one Metaverse Object's values, including those on the accounts joined to it.
 
    .PARAMETER Id
        Gets one value by its ID, whatever its state: its Status may also be Released, when nothing is waiting on a
        decision for it.
 
    .PARAMETER Summary
        Returns the counts instead of the values. Narrowed by -ConnectedSystemId and -SyncRuleId when given.
 
    .PARAMETER Page
        The page of values to return, counting from 1.
 
    .PARAMETER PageSize
        How many values each page holds.
 
    .PARAMETER All
        Returns every page of values rather than one. It stops after 1,000 pages, about 50,000 values at the default
        page size, with a warning; -Force reads on. Cannot be used with -Page.
 
    .PARAMETER Force
        With -All, reads every page, past the 1,000-page limit.
 
    .OUTPUTS
        By default, the values waiting on a decision, newest first. With -Id, that value. With -Summary, how many
        values are in each state.
 
    .EXAMPLE
        Get-JIMGeneratedValueDecision -Summary
 
        Reports how many values need a decision, how many renames are waiting for the next export, and how many
        values JIM corrected in the last seven days.
 
    .EXAMPLE
        Get-JIMGeneratedValueDecision -Status NeedsDecision |
            Select-Object MetaverseObjectDisplayName, AttributeName, Value, Reason, RejectedByConnectedSystemName, AnchoredByConnectedSystemName
 
        Lists the values waiting on a decision, with who they belong to and why each is held.
 
    .EXAMPLE
        Get-JIMGeneratedValueDecision -ConnectedSystemId 3 -All
 
        Lists every held value involving Connected System 3, following pagination.
 
    .LINK
        Approve-JIMGeneratedValueRename
        Reset-JIMGeneratedValueDecision
        Get-JIMGeneratedValue
        Set-JIMSyncRuleMapping
    #>

    [CmdletBinding(DefaultParameterSetName = 'List')]
    [OutputType('JIM.GeneratedValueDecisionDto', ParameterSetName = 'List')]
    [OutputType('JIM.GeneratedValueDecisionDto', ParameterSetName = 'ListAll')]
    [OutputType('JIM.GeneratedValueDecisionDto', ParameterSetName = 'ById')]
    [OutputType('JIM.GeneratedValueDecisionSummary', ParameterSetName = 'Summary')]
    param(
        [Parameter(ParameterSetName = 'List')]
        [Parameter(ParameterSetName = 'ListAll')]
        [Parameter(ParameterSetName = 'Summary')]
        [int]$ConnectedSystemId,

        [Parameter(ParameterSetName = 'List')]
        [Parameter(ParameterSetName = 'ListAll')]
        [Parameter(ParameterSetName = 'Summary')]
        [int]$SyncRuleId,

        [Parameter(ParameterSetName = 'List')]
        [Parameter(ParameterSetName = 'ListAll')]
        [ValidateSet('NeedsDecision', 'RenameAllowed')]
        [string]$Status,

        [Parameter(ParameterSetName = 'List')]
        [Parameter(ParameterSetName = 'ListAll')]
        [guid]$MetaverseObjectId,

        [Parameter(Mandatory, ParameterSetName = 'ById')]
        [guid]$Id,

        [Parameter(Mandatory, ParameterSetName = 'Summary')]
        [switch]$Summary,

        [Parameter(ParameterSetName = 'List')]
        [ValidateRange(1, [int]::MaxValue)]
        [int]$Page = 1,

        [Parameter(ParameterSetName = 'List')]
        [Parameter(ParameterSetName = 'ListAll')]
        [ValidateRange(1, 100)]
        [int]$PageSize = 50,

        [Parameter(Mandatory, ParameterSetName = 'ListAll')]
        [switch]$All,

        [Parameter(ParameterSetName = 'ListAll')]
        [switch]$Force
    )

    process {
        if (-not $script:JIMConnection) {
            Write-Error "You are not connected to JIM. Run Connect-JIM -Url <your JIM URL> to authenticate, then try again."
            return
        }

        if ($PSCmdlet.ParameterSetName -eq 'ById') {
            Write-Verbose "Getting generated value decision: $Id"
            Invoke-JIMApi -Endpoint "/api/v1/generated-values/decisions/$Id"
            return
        }

        $criteria = @()
        if ($PSBoundParameters.ContainsKey('ConnectedSystemId')) { $criteria += "connectedSystemId=$ConnectedSystemId" }
        if ($PSBoundParameters.ContainsKey('SyncRuleId')) { $criteria += "syncRuleId=$SyncRuleId" }

        if ($PSCmdlet.ParameterSetName -eq 'Summary') {
            Write-Verbose "Getting the generated value decision summary"
            $query = if ($criteria.Count -gt 0) { '?' + ($criteria -join '&') } else { '' }
            Invoke-JIMApi -Endpoint "/api/v1/generated-values/decisions/summary$query"
            return
        }

        if ($Status) { $criteria += "status=$Status" }
        if ($PSBoundParameters.ContainsKey('MetaverseObjectId')) { $criteria += "metaverseObjectId=$MetaverseObjectId" }
        $criteriaSuffix = if ($criteria.Count -gt 0) { '&' + ($criteria -join '&') } else { '' }

        if ($All) {
            Write-Verbose "Getting every generated value held for a decision"
            $pageRequest = {
                param($p)
                Invoke-JIMApi -Endpoint "/api/v1/generated-values/decisions?page=$p&pageSize=$PageSize$criteriaSuffix"
            }

            Invoke-JIMPagedFetch -PageRequest $pageRequest -CmdletName 'Get-JIMGeneratedValueDecision' -PageSize $PageSize -Force:$Force `
                -ItemNoun 'generated value decisions' -NarrowHint 'narrow the query with -ConnectedSystemId, -SyncRuleId or -Status'
            return
        }

        Write-Verbose "Getting generated values held for a decision (Page: $Page, PageSize: $PageSize)"
        $response = Invoke-JIMApi -Endpoint "/api/v1/generated-values/decisions?page=$Page&pageSize=$PageSize$criteriaSuffix"
        foreach ($item in $response.items) {
            $item
        }
    }
}