<#
.SYNOPSIS

{{{summary}}}{{^summary}}No summary available.{{/summary}}

.DESCRIPTION

{{{description}}}{{^description}}No description available.{{/description}}

.PARAMETER Json

JSON object

.OUTPUTS

{{{classname}}}<PSCustomObject>
#>
function ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{classname}}} {
    [CmdletBinding()]
    Param (
        [AllowEmptyString()]
        [string]$Json
    )

    Process {
        $match = 0
        $matchType = $null
        $matchInstance = $null

        {{#isNullable}}
        # nullable check
        if ([string]::IsNullOrEmpty($Json) -or $Json -eq "{}") {
            return [PSCustomObject]@{
                "ActualType" = $null
                "ActualInstance" = $null
                "OneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
            }
        }

        {{/isNullable}}
        {{#useOneOfDiscriminatorLookup}}
        {{#discriminator}}
        {{#mappedModels}}
        {{#-first}}
        $JsonData = ConvertFrom-Json -InputObject $Json
        {{/-first}}
        # check if the discriminator value is '{{{mappingName}}}'
        if ($JsonData.PSobject.Properties["{{{propertyBaseName}}}"].value -eq "{{{mappingName}}}") {
            # try to match {{{modelName}}} defined in the oneOf schemas
            try {
                $matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{modelName}}} $Json

                foreach($property in $matchInstance.PsObject.Properties) {
                    if ($null -ne $property.Value) {
                        $matchType = "{{{modelName}}}"
                        return [PSCustomObject]@{
                            "ActualType" = ${matchType}
                            "ActualInstance" = ${matchInstance}
                            "oneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
                        }
                    }
                }
            } catch {
                # fail to match the schema defined in oneOf with the discriminator lookup, proceed to the next one
                Write-Debug "Failed to match '{{{modelName}}}' defined in oneOf ({{{apiNamePrefix}}}{{{classname}}}) using the discriminator lookup ({{{mappingName}}}). Proceeding with the typical oneOf type matching."
            }
        }

        {{/mappedModels}}
        {{/discriminator}}
        {{/useOneOfDiscriminatorLookup}}
        {{#oneOf}}
        # try to match {{{.}}} defined in the oneOf schemas
        try {
            $matchInstance = ConvertFrom-{{{apiNamePrefix}}}JsonTo{{{.}}} $Json

            foreach($property in $matchInstance.PsObject.Properties) {
                if ($null -ne $property.Value) {
                    $matchType = "{{{.}}}"
                    $match++
                    break
                }
            }
        } catch {
            # fail to match the schema defined in oneOf, proceed to the next one
            Write-Debug "Failed to match '{{{.}}}' defined in oneOf ({{{apiNamePrefix}}}{{{classname}}}). Proceeding to the next one if any."
        }

        {{/oneOf}}
        if ($match -gt 1) {
            throw "Error! The JSON payload matches more than one type defined in oneOf schemas ({{{oneOf}}}). JSON Payload: $($Json)"
        } elseif ($match -eq 1) {
            return [PSCustomObject]@{
                "ActualType" = ${matchType}
                "ActualInstance" = ${matchInstance}
                "OneOfSchemas" = @({{#oneOf}}"{{{.}}}"{{^-last}}, {{/-last}}{{/oneOf}})
            }
        } else {
            throw "Error! The JSON payload doesn't matches any type defined in oneOf schemas ({{{oneOf}}}). JSON Payload: $($Json)"
        }
    }
}
