$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";
            } `
            -User $User `
            ".alias |= [((. // [])[] | select(.name != env(Name)))] + [{ name: env(Name), value: env(Value) }]";
    }

    <#
        .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";
            } `
            -User $User `
            ".env |= [((. // [])[] | select(.name != env(Name)))] + [{ name: env(Name), value: env(Value) }]";
    }

    <#
        .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
        )

        $flags = @();

        if ($User) {
            $flags = @("-u", "$User")
            $path = "$($IsWindows ? "~" : "$(sudo @flags 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 @using:flags pwsh -CommandWithArgs 'Get-Content -Raw $args[0]' $using:path | Set-Content $file;
            yq -i $using:Script $file;
            sudo @using:flags pwsh -CommandWithArgs 'Set-Content $args[0] -Value $args[1]' $using:path (Get-Content -Raw $file);
            Remove-Item $file;
        } | Receive-Job -Wait;
    }

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