Brickset.psm1

<#
    ______ _ _ _ ___ ___ _ _
    | ___ \ (_) | | | | | \/ | | | | |
    | |_/ /_ __ _ ___| | _____ ___| |_| . . | ___ __| |_ _| | ___
    | ___ \ '__| |/ __| |/ / __|/ _ \ __| |\/| |/ _ \ / _` | | | | |/ _ \
    | |_/ / | | | (__| <\__ \ __/ |_| | | | (_) | (_| | |_| | | __/
    \____/|_| |_|\___|_|\_\___/\___|\__\_| |_/\___/ \__,_|\__,_|_|\___|
 
#>


# --- Clean up bricksetConnection variable on module remove
$ExecutionContext.SessionState.Module.OnRemove = {

    Remove-Variable -Name bricksetConnection -Force -ErrorAction SilentlyContinue

}
<#
    - Function: xCheckScriptBricksetConnection
#>


function xCheckScriptBricksetConnection {
<#
    .SYNOPSIS
    Checks for the presence of $Script:BricksetConnection
 
    .DESCRIPTION
    Checks for the presence of $Script:BricksetConnection
 
    .INPUTS
    None
 
    .OUTPUTS
    None
 
    .EXAMPLE
    xCheckScriptBricksetConnection
#>


[CmdletBinding()]

    Param (

    )
    # --- Test for Brickset Connection
    if (-not $Script:BricksetConnection){

        throw "Brickset Connection variable does not exist. Please run Connect-Brickset first to create it"
    }
}

<#
    - Function: xCheckUserHash
#>


function xCheckUserHash{
<#
    .SYNOPSIS
    Checks for the presence of $Script:BricksetConnection.UserHash
 
    .DESCRIPTION
    Checks for the presence of $Script:BricksetConnection.UserHash
 
    .INPUTS
    None
 
    .OUTPUTS
    None
 
    .EXAMPLE
    xCheckUserHash
#>


[CmdletBinding()]

    Param (

    )
    # --- Test for Brickset Connection
    if (-not $Script:BricksetConnection.userHash){

        throw "Brickset UserHash created from your Brickset login credentials does not exist. Please run Connect-Brickset first to create it"
    }
}

<#
    - Function: Connect-Brickset
#>


function Connect-Brickset {
<#
    .SYNOPSIS
    Make a connection to the Brickset API
 
    .DESCRIPTION
    Make a connection to the Brickset API. Set the Brickset API Key and UserHash
 
    .PARAMETER APIKey
    API Key
 
    .PARAMETER Credential
    Supply Brickset Credentials
 
    .INPUTS
    System.String
    Management.Automation.PSCredential
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Connect-Brickset -APIKey 'Tk5C-KTA2-Gw2Q'
 
    .EXAMPLE
    $cred = Get-Credential
    Connect-Brickset -APIKey 'Tk5C-KTA2-Gw2Q' -Credential $cred
#>

[CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (

    [parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [String]$apiKey,

    [Parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [Management.Automation.PSCredential]$credential
    )

    try {

        # --- Create Output Object
        $Script:bricksetConnection = [pscustomobject]@{

            apiKey = $apiKey
            userHash = $null
            url = 'https://brickset.com/api/v3.asmx'
        }

        # --- Update BricksetConnection with UserHash
        if ($PSBoundParameters.ContainsKey("credential")){

            $username = $credential.UserName
            $password = $credential.GetNetworkCredential().Password

            $contentType = 'application/x-www-form-urlencoded'

            $body = @{
                apiKey = $Script:bricksetConnection.apiKey
                username = $username
                password = $password
            }

            $response = Invoke-RestMethod -Method POST -Uri 'https://brickset.com/api/v3.asmx/login' -ContentType $contentType -body $body

            $Script:bricksetConnection.userHash = $response.hash
        }

    }
    catch [Exception]{

        throw
    }
    finally {

        Write-Output $bricksetConnection
    }
}

<#
    - Function: Disconnect-Brickset
#>


function Disconnect-Brickset {
<#
    .SYNOPSIS
    Disconnect from the Brickset API
 
    .DESCRIPTION
    Disconnect from the Brickset API by removing the script BricksetConnection variable from PowerShell
 
    .EXAMPLE
    Disconnect-Brickset
 
    .EXAMPLE
    Disconnect-Brickset -Confirm:$false
#>

[CmdletBinding(SupportsShouldProcess,ConfirmImpact="High")]

    Param ()

    # --- Check for the presence of $Script:BricksetConnection
    xCheckScriptBricksetConnection

    if ($PSCmdlet.ShouldProcess($Script:BricksetConnection.url)){

        try {

            Write-Verbose -Message "Removing BricksetConnection Script Variable"
            Remove-Variable -Name BricksetConnection -Scope Script -Force -ErrorAction SilentlyContinue
        }
        catch [Exception]{

            throw

        }
    }
}

<#
    - Function: Get-BricksetCollectionUserNotes
#>


function Get-BricksetCollectionUserNotes {
    <#
    .SYNOPSIS
    Get all a user's set notes.
 
    .DESCRIPTION
    Get all a user's set notes.
 
    .INPUTS
    None
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetCollectionUserNotes
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param()

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        # --- Make the REST Call
        $body = @{
            apiKey   = $Script:BricksetConnection.apiKey
            userHash = $Script:BricksetConnection.userHash
        }

        Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getUserNotes' -Body $body

        $response.userNotes
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetMinifigCollectionOwned
#>


function Get-BricksetMinifigCollectionOwned {
    <#
    .SYNOPSIS
    Get Brickset Minifg Collection Owned
 
    .DESCRIPTION
    Get Brickset Minifg Collection Owned
 
    .INPUTS
    None
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetMinifigCollectionOwned
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param ()

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        # - Prepare the JSON params
        $jsonParams = [PSCustomObject] @{

            owned = '1'
        }

        $stringParam = $jsonParams | ConvertTo-Json -Compress

        Write-Verbose "jsonParams are: $stringParam"

        # --- Make the REST Call
        $body = @{
            apiKey   = $Script:BricksetConnection.apiKey
            userHash = $Script:BricksetConnection.userHash
            params   = $stringParam
        }

        Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getMinifigCollection' -Body $body

        $response.minifigs
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetMinifigCollectionWanted
#>


function Get-BricksetMinifigCollectionWanted {
    <#
    .SYNOPSIS
    Get Brickset Minifg Collection Wanted
 
    .DESCRIPTION
    Get Brickset Minifg Collection Wanted
 
    .INPUTS
    None
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetMinifigCollectionWanted
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param ()

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        # - Prepare the JSON params
        $jsonParams = [PSCustomObject] @{

            wanted    = '1'
        }

        $stringParam = $jsonParams | ConvertTo-Json -Compress

        Write-Verbose "jsonParams are: $stringParam"

        # --- Make the REST Call
        $body = @{
            apiKey   = $Script:BricksetConnection.apiKey
            userHash = $Script:BricksetConnection.userHash
            params   = $stringParam
        }

        Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getMinifigCollection' -Body $body

        $response.minifigs
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetSet
#>


function Get-BricksetSet {
    <#
    .SYNOPSIS
    Get Brickset Sets
 
    .DESCRIPTION
    Get Brickset Sets
 
    .PARAMETER Theme
    Brickset Theme
 
    .PARAMETER Subtheme
    Brickset Subtheme
 
    .PARAMETER Year
    Year
 
    .PARAMETER SetNumber
    Lego Set Number in the format {number}-{variant}, e.g. 6905-1
 
    .PARAMETER OrderBy
    Specify Sort Order
 
    .PARAMETER PageSize
    Specify how many records to return
 
    .INPUTS
    System.String.
    System.Int
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' -Subtheme 'Temple of Doom'
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' -Year 2009
 
    .EXAMPLE
    Get-BricksetSet -SetNumber '7199-1'
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' -OrderBy Pieces
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param (

        [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$theme,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [String]$subTheme,

        [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        $year,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [String]$setNumber,

        [parameter(Mandatory = $false)]
        [ValidateSet('Number', 'YearFrom', 'Pieces', 'Minifigs', 'Rating', 'UKRetailPrice', 'USRetailPrice', 'CARetailPrice', 'DERetailPrice', 'FRRetailPrice',
            'UKPricePerPiece', 'USPricePerPiece', 'CAPricePerPiece', 'DEPricePerPiece', 'FRPricePerPiece', 'Theme', 'Subtheme', 'Name', 'Random', 'QtyOwned', 'OwnCount', 'WantCount', 'UserRating', 'CollectionID')]
        [String]$orderBy,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [Int]$pageSize = 500
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }

    process {

        try {

            # - Prepare the JSON params
            $jsonParams = [PSCustomObject] @{

                pageSize = $pageSize
            }

            if ($PSBoundParameters.ContainsKey('theme')) {

                $jsonParams | Add-Member -MemberType NoteProperty -Name 'theme' -Value $theme
            }
            if ($PSBoundParameters.ContainsKey('subTheme')) {

                $jsonParams | Add-Member -MemberType NoteProperty -Name 'subtheme' -Value $subTheme
            }
            if ($PSBoundParameters.ContainsKey('year')) {

                $jsonParams | Add-Member -MemberType NoteProperty -Name 'year' -Value $year
            }
            if ($PSBoundParameters.ContainsKey('setNumber')) {

                $jsonParams | Add-Member -MemberType NoteProperty -Name 'setNumber' -Value $setNumber
            }
            if ($PSBoundParameters.ContainsKey('orderBy')) {

                $jsonParams | Add-Member -MemberType NoteProperty -Name 'orderBy' -Value $orderBy
            }

            $stringParam = $jsonParams | ConvertTo-Json -Compress

            Write-Verbose "jsonParams are: $stringParam"

            # --- Make the REST Call
            $body = @{
                apiKey   = $Script:BricksetConnection.apiKey
                userHash = $null
                params   = $stringParam
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getSets' -Body $body

            $response.sets
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Get-BricksetSetAdditionalImage
#>


function Get-BricksetSetAdditionalImage {
    <#
    .SYNOPSIS
    Get Brickset Set Additional Images
 
    .DESCRIPTION
    Get Brickset Set Additional Images
 
    .PARAMETER setId
    Brickset SetId (not the Lego Set Number)
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSetAdditionalImage -SetId 6905
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' | Get-BricksetSetAdditionalImage
 
    .EXAMPLE
    Get-BricksetSetAdditionalImage -SetId 6905 | Select-Object -ExpandProperty imageurl | Foreach-Object {Invoke-Expression 'cmd.exe /C start $_'}
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (
        [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }
    process {

        try {

            # --- Make the REST Call
            $body = @{
                apiKey = $Script:BricksetConnection.apiKey
                setId  = $setId
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getAdditionalImages' -Body $body

            $response.additionalImages
        }
        catch [Exception] {

            throw
        }
    }
    end {

    }
}

<#
    - Function: Get-BricksetSetInstructions
#>


function Get-BricksetSetInstructions {
    <#
    .SYNOPSIS
    Get Brickset Set Instructions
 
    .DESCRIPTION
    Get Brickset Set Instructions
 
    .PARAMETER setId
    Brickset SetId (not the Lego Set Number)
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSetInstructions -SetId 6905
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' | Get-BricksetSetInstructions
 
    .EXAMPLE
    Get-BricksetSet -SetNumber 75055-1 | Get-BricksetSetInstructions | Select-Object -First 1 -ExpandProperty url | Foreach-Object {Invoke-Expression 'cmd.exe /C start $_'}
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' | Get-BricksetSetInstructions | Select-Object -ExpandProperty url | ForEach-Object {$file = ($_.split('/'))[-1]; Start-BitsTransfer -Source $_ -Destination "C:\Users\jmedd\Documents\$file"}
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (
        [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }
    process {

        try {

            # --- Make the REST Call
            $body = @{
                apiKey = $Script:BricksetConnection.apiKey
                setId  = $setId
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getInstructions' -Body $body

            $response.instructions
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Get-BricksetSetOwned
#>


function Get-BricksetSetOwned {
    <#
    .SYNOPSIS
    Get Brickset Sets Owned
 
    .DESCRIPTION
    Get Brickset Sets Owned
 
    .PARAMETER orderBy
    Specify Sort Order
 
    .PARAMETER pageSize
    Specify how many records to return
 
    .INPUTS
    System.String.
    System.Int.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSetOwned -OrderBy Pieces
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (
        [parameter(Mandatory = $false)]
        [ValidateSet('Number', 'YearFrom', 'Pieces', 'Minifigs', 'Rating', 'UKRetailPrice', 'USRetailPrice', 'CARetailPrice', 'DERetailPrice', 'FRRetailPrice',
            'UKPricePerPiece', 'USPricePerPiece', 'CAPricePerPiece', 'DEPricePerPiece', 'FRPricePerPiece', 'Theme', 'Subtheme', 'Name', 'Random', 'QtyOwned', 'OwnCount', 'WantCount', 'UserRating', 'CollectionID')]
        [String]$orderBy,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [Int]$pageSize = 500
    )

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        # - Prepare the JSON params
        $jsonParams = [PSCustomObject] @{

            owned    = '1'
            pageSize = $pageSize
        }

        if ($PSBoundParameters.ContainsKey('orderBy')) {

            $jsonParams | Add-Member -MemberType NoteProperty -Name 'orderBy' -Value $orderBy
        }

        $stringParam = $jsonParams | ConvertTo-Json -Compress

        Write-Verbose "jsonParams are: $stringParam"

        # --- Make the REST Call
        $body = @{
            apiKey   = $Script:BricksetConnection.apiKey
            userHash = $Script:BricksetConnection.userHash
            params   = $stringParam
        }

        Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getSets' -Body $body

        $response.sets
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetSetReview
#>


function Get-BricksetSetReview {
    <#
    .SYNOPSIS
    Get Brickset Set Reviews
 
    .DESCRIPTION
    Get Brickset Set Reviews
 
    .PARAMETER SetId
    Brickset SetId (not the Lego Set Number)
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSetReview -SetId 6905
 
    .EXAMPLE
    Get-BricksetSet -Theme 'Indiana Jones' | Get-BricksetSetReview
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (
        [parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }
    process {

        try {

            # --- Make the REST Call
            $body = @{
                apiKey = $Script:BricksetConnection.apiKey
                setId  = $setId
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getReviews' -Body $body

            $response.reviews
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Get-BricksetSetWanted
#>


function Get-BricksetSetWanted {
    <#
    .SYNOPSIS
    Get Brickset Sets Wanted
 
    .DESCRIPTION
    Get Brickset Sets Wanted
 
    .PARAMETER orderBy
    Specify Sort Order
 
    .PARAMETER pageSize
    Specify how many records to return
 
    .INPUTS
    System.String.
    System.Int.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSetWanted -OrderBy Pieces
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    Param
    (
        [parameter(Mandatory = $false)]
        [ValidateSet('Number', 'YearFrom', 'Pieces', 'Minifigs', 'Rating', 'UKRetailPrice', 'USRetailPrice', 'CARetailPrice', 'DERetailPrice', 'FRRetailPrice',
            'UKPricePerPiece', 'USPricePerPiece', 'CAPricePerPiece', 'DEPricePerPiece', 'FRPricePerPiece', 'Theme', 'Subtheme', 'Name', 'Random', 'QtyOwned', 'OwnCount', 'WantCount', 'UserRating', 'CollectionID')]
        [String]$orderBy,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [Int]$pageSize = 500
    )

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        # - Prepare the JSON params
        $jsonParams = [PSCustomObject] @{

            wanted   = '1'
            pageSize = $pageSize
        }

        if ($PSBoundParameters.ContainsKey('orderBy')) {

            $jsonParams | Add-Member -MemberType NoteProperty -Name 'orderBy' -Value $orderBy
        }

        $stringParam = $jsonParams | ConvertTo-Json -Compress

        Write-Verbose "jsonParams are: $stringParam"

        # --- Make the REST Call
        $body = @{
            apiKey   = $Script:BricksetConnection.apiKey
            userHash = $Script:BricksetConnection.userHash
            params   = $stringParam
        }

        Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getSets' -Body $body

        $response.sets
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetSubtheme
#>


function Get-BricksetSubtheme {
    <#
    .SYNOPSIS
    Get Brickset Subthemes for a given Theme
 
    .DESCRIPTION
    Get Brickset Subthemes for a given Theme
 
    .PARAMETER Theme
    Brickset Theme
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetSubtheme -Theme 'Indiana Jones'
 
    .EXAMPLE
    Get-BricksetTheme | Where-Object {$_.Theme -eq 'Indiana Jones'} | Get-BricksetSubtheme
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param
    (
        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$theme
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }

    process {

        try {

            # --- Make the REST Call
            $body = @{
                apiKey = $Script:BricksetConnection.apiKey
                Theme  = $theme
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getSubthemes' -Body $body

            $response.subthemes
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Get-BricksetTheme
#>


function Get-BricksetTheme {
    <#
    .SYNOPSIS
    Get Brickset Themes
 
    .DESCRIPTION
    Get Brickset Themes
 
    .INPUTS
    None
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetTheme
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param()

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Make the REST Call
        $body = @{
            apiKey = $Script:BricksetConnection.apiKey
        }

        $response = Invoke-BricksetRestMethod -Method POST -URI '/getThemes' -Body $body

        $response.themes
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Get-BricksetYear
#>


function Get-BricksetYear {
    <#
    .SYNOPSIS
    Get Brickset Years for a given Theme
 
    .DESCRIPTION
    Get Brickset Years for a given Theme
 
    .PARAMETER Theme
    Brickset Theme
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    Get-BricksetYear
 
    .EXAMPLE
    Get-BricksetYear -Theme 'Indiana Jones'
 
    .EXAMPLE
    Get-BricksetTheme | Where-Object {$_.Theme -eq 'Indiana Jones'} | Get-BricksetYear
#>

    [CmdletBinding()][OutputType('System.Management.Automation.PSObject')]

    param
    (
        [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$theme
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection
    }

    process {

        try {

            # --- Make the REST Call
            $body = @{
                apiKey = $Script:BricksetConnection.apiKey
                Theme  = $theme
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            $response = Invoke-BricksetRestMethod -Method POST -URI '/getYears' -Body $body

            $response.years
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Invoke-BricksetRestMethod
#>


function Invoke-BricksetRestMethod {
<#
    .SYNOPSIS
    Wrapper for Invoke-RestMethod/Invoke-WebRequest with Brickset specifics
 
    .DESCRIPTION
    Wrapper for Invoke-RestMethod/Invoke-WebRequest with Brickset specifics
 
    .PARAMETER Method
    REST Method:
    Supported Methods: GET, POST, PUT,DELETE
 
    .PARAMETER URI
    API URI, e.g. /getThemes
 
    .PARAMETER Headers
    Optionally supply custom headers
 
    .PARAMETER Body
    REST Body in JSON format
 
    .PARAMETER OutFile
    Save the results to a file
 
    .PARAMETER WebRequest
    Use Invoke-WebRequest rather than the default Invoke-RestMethod
 
    .INPUTS
    System.String
    Switch
 
    .OUTPUTS
    System.Management.Automation.PSObject
 
    .EXAMPLE
    $body = @{
        apiKey ='4-r6wS-3JSq-xIpLe'
    }
 
    Invoke-BricksetRestMethod -Method POST -URI '/getThemes' -Body $body
#>

[CmdletBinding(DefaultParameterSetName="Standard")][OutputType('System.Management.Automation.PSObject')]

    Param (

        [Parameter(Mandatory=$true, ParameterSetName="Standard")]
        [Parameter(Mandatory=$true, ParameterSetName="Body")]
        [Parameter(Mandatory=$true, ParameterSetName="OutFile")]
        [ValidateSet("GET","POST","PUT","DELETE")]
        [String]$method,

        [Parameter(Mandatory=$true, ParameterSetName="Standard")]
        [Parameter(Mandatory=$true, ParameterSetName="Body")]
        [Parameter(Mandatory=$true, ParameterSetName="OutFile")]
        [ValidateNotNullOrEmpty()]
        [String]$uri,

        [Parameter(Mandatory=$false, ParameterSetName="Standard")]
        [Parameter(Mandatory=$false, ParameterSetName="Body")]
        [Parameter(Mandatory=$false, ParameterSetName="OutFile")]
        [ValidateNotNullOrEmpty()]
        [System.Collections.IDictionary]$headers,

        [Parameter(Mandatory=$false, ParameterSetName="Body")]
        [ValidateNotNullOrEmpty()]
        [Hashtable]$body,

        [Parameter(Mandatory=$false, ParameterSetName="OutFile")]
        [ValidateNotNullOrEmpty()]
        [String]$outFile,

        [Parameter(Mandatory=$false, ParameterSetName="Standard")]
        [Parameter(Mandatory=$false, ParameterSetName="Body")]
        [Parameter(Mandatory=$false, ParameterSetName="OutFile")]
        [Switch]$webRequest
    )

    # --- Test for existing connection to vRA
    if (-not $Script:BricksetConnection){

        throw "Brickset Connection variable does not exist. Please run Connect-Brickset first to create it"
    }

    # --- Create Invoke-RestMethod Parameters
    $fullURI = "$($Script:BricksetConnection.url)$($uri)"


    # --- Set up default parmaeters
    $params = @{

        method = $method
        contentType = 'application/x-www-form-urlencoded'
        uri = $fullURI
    }

    # --- Add default headers if not passed
    if ($PSBoundParameters.ContainsKey("headers")){

        $params.Add('headers', $headers)
    }

    if ($PSBoundParameters.ContainsKey("body")){

        $params.Add("body", $body)

        # --- Log the payload being sent to the server
        Write-Debug -Message ($body | ConvertTo-Json -Depth 5)
    }

    if ($PSBoundParameters.ContainsKey("outfile")){

        $params.Add("outFile", $outFile)

    }

    try {

        # --- Use either Invoke-WebRequest or Invoke-RestMethod
        if ($WebRequest.IsPresent) {

            Invoke-WebRequest @params
        }
        else {

            Invoke-RestMethod @params
        }
    }
    catch {

        throw $_
    }
}

<#
    - Function: Set-BricksetMinifgCollectionOwned
#>


function Set-BricksetMinifgCollectionOwned {
    <#
    .SYNOPSIS
    Set a Brickset Minifg to Owned status
 
    .DESCRIPTION
    Set a Brickset Minfig to Owned status. Include the number of sets owned.
 
    .PARAMETER MinifigNumber
    Brickset MinifigNumber
 
    .PARAMETER QtyOwned
    Quantity Owned
 
    .INPUTS
    System.String
    System.Number
 
    .OUTPUTS
    None
 
    .EXAMPLE
    Set-BricksetMinifgCollectionOwned -MinifgNumber sw705 -QtyOwned 1
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]

    Param
    (
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$minifigNumber,

        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [Int]$qtyOwned
    )

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        if ($PSCmdlet.ShouldProcess($minifigNumber)) {

            # - Prepare the JSON params
            $jsonParams = [PSCustomObject] @{

                owned = '1'
                qtyOwned = $qtyOwned
            }

            $stringParam = $jsonParams | ConvertTo-Json -Compress

            Write-Verbose "jsonParams are: $stringParam"

            # --- Make the REST Call
            $body = @{
                apiKey   = $Script:BricksetConnection.apiKey
                userHash = $Script:BricksetConnection.userHash
                params   = $stringParam
                minifigNumber = $minifigNumber
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            Invoke-BricksetRestMethod -Method POST -URI '/setMinifigCollection' -Body $body
        }
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Set-BricksetMinifgCollectionWanted
#>


function Set-BricksetMinifgCollectionWanted {
    <#
    .SYNOPSIS
    Set a Brickset Minifg to Wanted status
 
    .DESCRIPTION
    Set a Brickset Minfig to Wanted status.
 
    .PARAMETER MinifigNumber
    Brickset MinifigNumber
 
    .INPUTS
    System.String
 
    .OUTPUTS
    None
 
    .EXAMPLE
    Set-BricksetMinifgCollectionWanted -MinifigNumber sw705
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]

    Param
    (
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$minifigNumber
    )

    try {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash

        if ($PSCmdlet.ShouldProcess($MinifigNumber)) {

            # - Prepare the JSON params
            $jsonParams = [PSCustomObject] @{

                want = '1'
            }

            $stringParam = $jsonParams | ConvertTo-Json -Compress

            Write-Verbose "jsonParams are: $stringParam"

            # --- Make the REST Call
            $body = @{
                apiKey        = $Script:BricksetConnection.apiKey
                userHash      = $Script:BricksetConnection.userHash
                params        = $stringParam
                minifigNumber = $minifigNumber
            }

            Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

            Invoke-BricksetRestMethod -Method POST -URI '/setMinifigCollection' -Body $body
        }
    }
    catch [Exception] {

        throw
    }
}

<#
    - Function: Set-BricksetSetOwned
#>


function Set-BricksetSetOwned {
    <#
    .SYNOPSIS
    Set a Brickset Set to Owned status
 
    .DESCRIPTION
    Set a Brickset Set to Owned status. Include the number of sets owned.
 
    .PARAMETER SetId
    Brickset SetId
 
    .PARAMETER QtyOwned
    Quantity Owned
 
    .PARAMETER Rating
    Supply a rating from 1 - 5
 
    .PARAMETER UserNotes
    Supply User Notes
 
    .INPUTS
    System.String
    System.Number
 
    .OUTPUTS
    None
 
    .EXAMPLE
    Set-BricksetSetOwned -SetId 26049 -QtyOwned 1 -Rating 5 -UserNotes 'One of my favourite sets'
 
    .EXAMPLE
    Get-BricksetSet -SetNumber '7199-1' | Set-BricksetSetOwned -QtyOwned 1 -Confirm:$false
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]

    param
    (
        [parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId,

        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [Int]$qtyOwned,

        [parameter(Mandatory = $false)]
        [ValidateSet(1, 2, 3, 4, 5)]
        [Int]$rating,

        [parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [String]$userNotes
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash
    }

    process {

        try {

            if ($PSCmdlet.ShouldProcess($setId)) {

                # - Prepare the JSON params
                $jsonParams = [PSCustomObject] @{

                    own      = '1'
                    qtyOwned = $qtyOwned
                }

                if ($PSBoundParameters.ContainsKey('rating')) {

                    $jsonParams | Add-Member -MemberType NoteProperty -Name 'rating' -Value $rating
                }
                if ($PSBoundParameters.ContainsKey('userNotes')) {

                    $jsonParams | Add-Member -MemberType NoteProperty -Name 'notes' -Value $userNotes
                }

                $stringParam = $jsonParams | ConvertTo-Json -Compress

                Write-Verbose "jsonParams are: $stringParam"

                # --- Make the REST Call
                $body = @{
                    apiKey   = $Script:BricksetConnection.apiKey
                    userHash = $Script:BricksetConnection.userHash
                    params   = $stringParam
                    setID    = $setId
                }

                Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

                Invoke-BricksetRestMethod -Method POST -URI '/setCollection' -Body $body
            }
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Set-BricksetSetUnwanted
#>


function Set-BricksetSetUnwanted {
    <#
    .SYNOPSIS
    Set a Brickset Set to Unwanted status
 
    .DESCRIPTION
    Set a Brickset Set to Unwanted status
 
    .PARAMETER SetId
    Brickset SetId
 
    .INPUTS
    String
 
    .OUTPUTS
    None
 
    .EXAMPLE
    Set-BricksetSetUnwanted -SetId 26049
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]

    param
    (
        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash
    }

    process {

        try {

            if ($PSCmdlet.ShouldProcess($SetId)) {

                # - Prepare the JSON params
                $jsonParams = [PSCustomObject] @{

                    want = '0'
                }

                $stringParam = $jsonParams | ConvertTo-Json -Compress

                Write-Verbose "jsonParams are: $stringParam"

                # --- Make the REST Call
                $body = @{
                    apiKey   = $Script:BricksetConnection.apiKey
                    userHash = $Script:BricksetConnection.userHash
                    params   = $stringParam
                    setID    = $setId
                }

                Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

                Invoke-BricksetRestMethod -Method POST -URI '/setCollection' -Body $body
            }
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Set-BricksetSetWanted
#>


function Set-BricksetSetWanted {
    <#
    .SYNOPSIS
    Set a Brickset Set to Wanted status
 
    .DESCRIPTION
    Set a Brickset Set to Wanted status
 
    .PARAMETER SetId
    Brickset SetId
 
    .INPUTS
    String
 
    .OUTPUTS
    None
 
    .EXAMPLE
    Set-BricksetSetWanted -SetId 26049
#>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]

    param
    (
        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$setId
    )

    begin {

        # --- Check for the presence of $Script:BricksetConnection
        xCheckScriptBricksetConnection

        # --- Check for the UserHash
        xCheckUserHash
    }

    process {

        try {

            # --- Check for the presence of $Script:BricksetConnection
            xCheckScriptBricksetConnection

            # --- Check for the UserHash
            xCheckUserHash

            if ($PSCmdlet.ShouldProcess($setId)) {

                # - Prepare the JSON params
                $jsonParams = [PSCustomObject] @{

                    want = '1'
                }

                $stringParam = $jsonParams | ConvertTo-Json -Compress

                Write-Verbose "jsonParams are: $stringParam"

                # --- Make the REST Call
                $body = @{
                    apiKey   = $Script:BricksetConnection.apiKey
                    userHash = $Script:BricksetConnection.userHash
                    params   = $stringParam
                    setID    = $setId
                }

                Write-Verbose "Body is: $($body | ConvertTo-Json -Depth 5)"

                Invoke-BricksetRestMethod -Method POST -URI '/setCollection' -Body $body
            }
        }
        catch [Exception] {

            throw
        }
    }
}

<#
    - Function: Test-BricksetAPIKey
#>


function Test-BricksetAPIKey {
    <#
    .SYNOPSIS
    Test the Brickset API Key
 
    .DESCRIPTION
    Test the Brickset API Key
 
    .PARAMETER APIKey
    API Key
 
    .INPUTS
    System.String.
 
    .OUTPUTS
    System.Boolean
 
    .EXAMPLE
    Test-BricksetAPIKey -APIKey 'Tk5C-KTA2-Gw2Q'
#>

    [CmdletBinding()][OutputType('System.Boolean')]

    param
    (
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$apiKey
    )

    try {

        # --- Make the REST Call
        $body = @{
            apiKey = $apiKey
        }

        $contentType = 'application/x-www-form-urlencoded'

        $checkKey = Invoke-RestMethod -Method POST -Uri 'https://brickset.com/api/v3.asmx/checkKey' -ContentType $contentType -body $body

        if ($checkKey.status -eq 'success') {

            Write-Output $true
        }
        else {

            Write-Output $false
        }
    }
    catch [Exception] {

        throw
    }
}