<#
.SYNOPSIS
    A short one-line action-based description, e.g. 'Tests if a function is valid'
.DESCRIPTION
    A longer description of the function, its purpose, common use cases, etc.
.NOTES
    Information or caveats about the function e.g. 'This function is not supported in Linux'
.LINK
    Specify a URI to a help page, this will show when Get-Help -Online is used.
.EXAMPLE
    Test-MyTestFunction -Verbose
    Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
#>

function New-ITDPassword {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        #[ValidateSet('Office365', 'VMware_Systems', 'CSRC', 'Shared Linux Password List', 'Peoplesoft Share PW', 'Cohesity', 'VDI')]
        [string]
        $PasswordList,

        [Parameter(Mandatory = $true)]
        [string]
        $Title,

        [Parameter(Mandatory = $true)]
        [string]
        $Description,

        [string]
        $AccountType,

        [Parameter(ParameterSetName = 'GeneratePassword', Mandatory)]
        [string]
        $UserName,

        [string]
        $Notes,

        [Parameter(ParameterSetName = 'EnterCredential')]
        [PSCredential]
        $CredentialToSave,

        [PSCredential]
        $Credential
    )
    
    begin {
        $PSList = Get-ITDPasswordList -PasswordList $PasswordList -Credential $Credential
        If (@($PSList).count -gt 1) { Write-Error "More than one PasswordList match." -ErrorAction Stop }
    }
    
    process {
        switch ($PSCmdlet.ParameterSetName) {
            'EnterCredential' {
                Write-Verbose -Message "EnterCredential"
                $Username = $CredentialToSave.UserName
                $Password = $CredentialToSave.GetNetworkCredential().Password
            }
            'GeneratePassword' {
                Write-Verbose -Message "GeneratePassword"
                $Password = New-ITDRandomPassword -Credential $Credential
            }
        }
        
        Write-Verbose -Message "Create password object"
        $PasswordObj = [PSCustomObject]@{
            'PasswordListID' = $PSList.PasswordListID;
            'Title'          = $Title;
            'Description'    = $Description;
            'UserName'       = $Username;
            'Password'       = $Password;
            'Notes'          = ("Auto-generated by " + $Credential.UserName + " @ " + (Get-Date -UFormat "%Y/%m/%d %H:%M:%S"));
        }

        switch ($PSBoundParameters.Keys) {
            Notes {
                $PasswordObj.Notes += ("`n" + $Notes)
            }
        }

        If ($AccountType) {
            $AccountTypeId = Get-ITDPasswordAccountTypeId -AccountType $AccountType
            $PasswordObj | Add-Member -Name AccountTypeId -MemberType NoteProperty -Value $AccountTypeId
        }
        else {
            $PasswordObj | Add-Member -Name AccountTypeId -MemberType NoteProperty -Value 0
        }

        $InvokeRestMethodParams = @{
            Method      = 'Post';
            Uri         = 'https://itdpv.nd.gov/winapi/passwords';
            ContentType = 'application/json';
            Body        = ($PasswordObj | ConvertTo-Json);
        }

        If ($PSBoundParameters.ContainsKey('Credential')){
            $InvokeRestMethodParams += @{Credential = $Credential}
        } Else {
            $InvokeRestMethodParams += @{UseDefaultCredentials = $true}
        }

        Write-Verbose -Message "Invoke Passwordstate record creation"
        $InvokeResult = Invoke-RestMethod @InvokeRestMethodParams

        #Write-Verbose -Message "Store Invoke result in variable"
        #$OutResult = $InvokeResult | Select-Object PasswordList, Title, Description, UserName, @{n = 'SecurePassword'; e = { $_.Password | ConvertTo-SecureString -AsPlainText -Force } }, AccountTypeId, AccountType
        <# storing the returned PSCredential object (see code above) sometimes causes the following error:
           [error] Exception calling ".ctor" with "2" argument(s): "Cannot process argument because the value of argument "password" is null. Change the value of argument "password" to a non-null value." 
           Running Get-ITDPassword does not cause the error, unsure of cause.  Unsure of the reason why, not looking into it further
        #>
        

        Write-Verbose -Message "Retrieve new password"
        $GetITDPasswordParams = @{
            Title = $Title;
            UserName = $UserName;
        }
        If ($PSBoundParameters.ContainsKey('Credential')){
            $GetITDPasswordParams += @{Credential = $Credential}
        } Else {
            $GetITDPasswordParams += @{UseDefaultCredentials = $true}
        }
        $OutResult = Get-ITDPassword @GetITDPasswordParams

        #Write-Verbose -Message "put OutResult in credential variable and return"
        #$OutCred = New-Object System.Management.Automation.PSCredential($OutResult.UserName, $OutResult.SecurePassword)
    }
    
    end {
        Write-Output $OutResult
    }
}