$null = New-Module {
    . "$PSScriptRoot/Constants.ps1";

    <#
        .SYNOPSIS
        Adds an alias to an existing `aliae` configuration.

        .PARAMETER Name
        The name of the alias to add.

        .PARAMETER Value
        The script the alias should point to.

        .PARAMETER User
        The user to add the alias to.
    #>
    function Add-Alias {
        param(
            [string] $Name,
            [string] $Value,
            [string] $User
        )

        Edit-Config `
            -Variables @{
                Name = "$Name";
                Value = "$Value";
            } `
            ".alias |= [((. // [])[] | select(.name != env.Name))] + [{ name: env.Name, value: env.Value }]" `
            -User $User;
    }

    <#
        .SYNOPSIS
        Adds an environment variable to an existing `aliae` configuration.

        .PARAMETER Name
        The name of the variable to add.

        .PARAMETER Value
        The value of the variable.
    #>
    function Add-EnvironmentVariable {
        param(
            [string] $Name,
            [string] $Value,
            [string] $User
        )

        Edit-Config `
            -Variables @{
                Name = "$Name";
                Value = "$Value";
            } `
            ".env |= [((. // [])[] | select(.name != env.Name))] + [{ name: env.Name, value: env.Value }]" `
            -User $User;
    }

    <#
        .SYNOPSIS
        Edits the underlying `aliae` configuration.

        .PARAMETER Script
        The yq script to run over the configuration.

        .PARAMETER User
        The user to edit the configuration for.
    #>
    function Edit-Config {
        param(
            [string] $Script,
            [hashtable] $Variables,
            [string] $User
        )

        if ($User) {
            $path = "$($IsWindows ? "~" : "$(sudo -u $User bash -c "realpath ~")")/.aliae.yaml";
        } else {
            $path = Get-GlobalConfigPath;
        }

        Start-Job {
            $file = New-TemporaryFile;
            $variables = $using:Variables;

            foreach ($key in $variables.Keys) {
                Set-Item "Env:\$key" $variables[$key];
            }

            sudo -u $using:User cp $using:path $file;
            yq -yi $using:Script $file;
            sudo -u $using:User cp $file $using:path;
            Remove-Item $file;
        } | Receive-Job -Wait;
    }

    Export-ModuleMember -Function Add-Alias,Add-EnvironmentVariable;
};