Class/UpdateContainersReplacementDefinition.Class.psm1

## Namespaces.
using namespace System.IO;
using namespace System.Text.Json;
using namespace System.Text.Json.Serialization;

## Definition Replacement Class.
class UpdateContainersReplacementDefinition
{
    <#
    .NAME
        UpdateContainersReplacementDefinition

    .SYNOPSIS
        Class defining a key-value replacement for paths and strings.

    .DESCRIPTION
        This class represents a key-value pair used for replacing placeholders
        in strings or paths, with an option to treat the value as a file system path.

    .PROPERTIES
        Key
            The placeholder key to be replaced in the target string.

        Path
            A boolean indicating whether the value should be treated as a file system path.

        Value
            The value to replace the key with, which can be a string or a path.
    #>


    ## Key Property.
    [JsonPropertyName('key')]
    [JsonRequired()]
    [String] $Key;

    ## The Path Property.
    [JsonPropertyName('path')]
    [Boolean] $Path = $false;

    ## Value Property.
    [JsonPropertyName('value')]
    [JsonRequired()]
    [String] $Value;

    ## Replace Method.
    [String] Replace([String] $value)
    {
        <#
        .NAME
            Replace

        .SYNOPSIS
            Replaces occurrences of the key in the provided value with the defined value.

        .DESCRIPTION
            This method searches for occurrences of the key, formatted as `%{key}%`,
            in the provided string and replaces them with the defined value. If the
            Path property is set to true, it treats the value as a file system path
            and resolves it accordingly.

        .PARAMETERS
            value
                The string in which to perform the replacement.
        #>


        ## Ensure we have a value to replace.
        if ($null -eq $value -or "" -eq $value.Trim()) { return $value; }

        ## Check for a path replacement.
        if ($this.Path)
        {
            ## Check check the operation system.
            if ([Environment]::OSVersion.Platform -eq [PlatformID]::Unix)
            {
                ## Replace any drive letters with empty in the value.
                $this.Value = $($this.Value.Trim() -replace "^[a-zA-Z]:", "").Trim();

                ## Replace any Windows-style backslashes with slashes in the value.
                $this.Value = $($this.Value.Trim() -replace "\\", "/").Trim();

                ## Replace any double slashes with a single slash in the value.
                $this.Value = $($this.Value.Trim() -replace "//", "/").Trim();
            }
            else
            {
                ## Replace any Unix-style slashes with backslashes in the value.
                $this.Value = $($this.Value.Trim() -replace "/", "\\").Trim();

                ## Replace any double backslashes with a single backslash in the value.
                $this.Value = $($this.Value.Trim() -replace "\\\\", "\\").Trim();

                ## Check for a leading backslash in the value.
                if ($this.Value.StartsWith("\"))
                {
                    ## Prepend the value with the current drive letter.
                    $this.Value = "$($([Path]::GetPathRoot((Get-Location).Path).Trim()))$($this.Value.Trim())".Trim();
                }
            }

            ## Resolve the path to ensure it exists.
            $resolvedPath = (Resolve-Path -Path $this.Value.Trim() -ErrorAction SilentlyContinue);

            ## Resolve the full path from the value.
            $this.Value = ($null -ne $resolvedPath ? $resolvedPath.Path.Trim() : $this.Value.Trim());
        }

        ## Return the replaced value.
        return ($value.Trim() -replace "%{$($this.Key.Trim())}%", $this.Value.Trim());
    }
};