$null = New-Module {
    . "$PSScriptRoot/../../Scripts/Scripting.ps1";
    . "$PSScriptRoot/../../Scripts/Software.ps1";

    <#
        .SYNOPSIS
        Adds an initialization script to the profile.

        .PARAMETER System
        A value indicating whether the script should be installed globally.

        .PARAMETER DefaultUser
        A value indicating whether the script should be installed to users by default.

        .PARAMETER HomeDir
        The path to the home directory of the user to install the script to.

        .PARAMETER Category
        The category name of the script to install.

        .PARAMETER Script
        The script to install.

        .PARAMETER Replace
        A value indicating whether the script should be replaced if it already exists.

        .PARAMETER Append
        A value indicating whether the content should be appended to the script if it already exists.
    #>
    function Add-PowerShellProfileStatement {
        param(
            [Parameter(ParameterSetName = "Global", Mandatory)]
            [switch] $System,
            [Parameter(ParameterSetName = "DefaultUser", Mandatory)]
            [switch] $DefaultUser,
            [Parameter(ParameterSetName = "Home")]
            [string] $HomeDir = "~",
            [Parameter(ParameterSetName = "Global", Mandatory)]
            [Parameter(ParameterSetName = "DefaultUser")]
            [Parameter(ParameterSetName = "Home")]
            [string] $Category = $null,
            [Parameter(Position = 0, Mandatory)]
            [string] $Script,
            [switch] $Replace,
            [switch] $Append
        )

        [System.Collections.ArrayList] $profiles = @();

        if ($System) {
            [string] $configRoot = $null;

            if ($IsWindows) {
                # ToDo Change to "PowerShell"
                $configRoot = "$env:ProgramData";
            } else {
                $configRoot = "/etc";
            }

            $profiles = @("$configRoot/powershell/.");
        } else {
            if ($DefaultUser) {
                if (-not $IsWindows) {
                    $HomeDir = "/etc/skel";
                } else {
                    $HomeDir = "C:/Users/Default";
                }
            }

            foreach ($shell in @("pwsh", "powershell")) {
                if (Test-Command $shell) {
                    $null = $profiles.Add((& $shell -NoProfile -c '$PROFILE'));
                }
            }

            Push-Location ~;

            $profiles = @(
                $profiles |
                    ForEach-Object { [System.IO.Path]::GetRelativePath((Get-Location), $_) } |
                    ForEach-Object { "$HomeDir/$_" }
            );

            Pop-Location;
        }

        if ($Category) {
            $profiles = @($profiles | ForEach-Object { Join-Path (Split-Path -Parent $_) "conf.d" "$Category.ps1" });
        }

        $profiles | ForEach-Object {
            $arguments = @{};

            if ($Replace.IsPresent) {
                $null = $arguments.Add("Replace", $Replace);
            }

            if ($Append.IsPresent) {
                $null = $arguments.Add("Append", $Append);
            }

            Write-PSScript @arguments `
                -FileName $_ `
                -Script $Script;
        };
    }

    <#
        .SYNOPSIS
        Creates an eval-script using the `[scriptblock]::Create` method.

        .PARAMETER Initializer
        The code to evaluate.
    #>
    function Get-ScriptInitializer {
        param (
            [Parameter(Position=0, Mandatory=$true)]
            $Initializer
        )

        return ". ([scriptblock]::Create(($Initializer) -join `"``n`"))";
    }
};