$ErrorActionPreference = 'Stop';
Set-StrictMode -Version '2.0'

$commonScriptDir = (Split-Path $script:MyInvocation.MyCommand.Path);


function Get-FileHashCustom {
    param(
        [Parameter(ValueFromPipeline = $true, Mandatory = $true)]
        [string]
        $Path,
        [string]
        $Algorithm = 'SHA256'
    )

    process {
        $Path = (resolve-path $Path)
        
        $fileStream = $null;
        $hashAlgorithm = $null;

        try {
            $fileStream = New-Object 'System.IO.FileStream' -ArgumentList @($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
            $hashAlgorithm = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)

            [byte[]]$hashBytes = $hashAlgorithm.ComputeHash($fileStream);
            $hash = [BitConverter]::ToString($hashBytes).Replace("-", "").ToLower();
            
            return New-Object 'PSObject' -Property @{
                Algorithm = 'SHA256';
                Hash = $hash;
                Path = $Path;
            };

        } finally {
            if ($fileStream) { try { $fileStream.Dispose(); } catch {} }
            if ($hashAlgorithm) { try { $hashAlgorithm.Dispose(); } catch {} }
        }
    }
}

function Get-ContentHash($Content, $Algorithm = 'SHA256') {
    $hashAlgorithm = $null;

    try {
        $hashAlgorithm = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)

        [byte[]]$contentBytes = [System.Text.Encoding]::UTF8.GetBytes($Content)

        [byte[]]$hashBytes = $hashAlgorithm.ComputeHash($contentBytes);
        $hash = [BitConverter]::ToString($hashBytes).Replace("-", "").ToLower();
        
        return $hash;

    } finally {
        if ($hashAlgorithm) { try { $hashAlgorithm.Dispose(); } catch {} }
    }
}