#!/bin/env fish
begin
    set -l dir (status dirname)

    functions -e installSW
    functions -e configureSW
    functions -e userConfig

    function runPSUserAction -a script action name
        pwsh -CommandWithArgs '& $args[0] $args[1] @{ name=$args[2]; }' "$script" "$action" "$name"
    end

    function runPSUserConfig -a script name
        runPSUserAction "$script" ConfigureUser "$name"
    end

    function inherit -a script -d "Inherits the installer from the specified script."
        set -l actions \
            installSW \
            install \
            configureSW \
            configure \
            userConfig \
            userConfig

        for i in (seq 1 2 (count $actions))
            set -l functionName "$actions[$i]Base"

            function $functionName -V script -V actions -V i
                fish "$script" $actions[(math $i + 1)] $argv
            end

            function $actions[$i] -V functionName
                $functionName $argv
            end
        end
    end

    function runInstaller -V dir -a action
        set -l path (status stack-trace | head -n4 | tail -n1 | string replace --regex -- '^\s*called on line \d+ of file (.*)$' '$1')
        set -l name (basename (dirname $path))
        runInstallerAction $name $argv
    end

    function runInstallerAction -V dir
        argparse "force" -- $argv
        set -l install
        set -l args $_flag_force
        set -l name $argv[1]
        set -l action $argv[2]
        source "$dir/settings.fish"

        if [ -n "$_flag_force" ]
            set force true
        else
            set force false
        end

        if isProgramEnabled $name || $force
            set install true
        else
            set install false
        end

        if [ -z "$action" ] || [ "$action" = install ]
            if functions -q installSW && $install
                echo "Installing `$name`..."
                installSW $argv[3..]
            end

            runInstallerAction $args $name configure

            if not isConfigured || [ "$USER" != (getConfig "valhalla.setupUser.name") ]
                runInstallerAction $args $name userConfig
            end
        else if [ "$action" = configure ]
            if functions -q configureSW && $install
                echo "Configuring `$name`..."
                configureSW $argv[3..]
            end
        else if [ "$action" = userConfig ]
            set -l user $argv[3]

            if [ -z "$user" ]
                set user "$USER"
            end

            if isProgramEnabled "$name" "$user" || $force
                set install true
            else
                set install false
            end

            if functions -q userConfig && $install
                echo "Configuring `$name` for `$user`..."
                userConfig "$user" $argv[4..]
            end
        end
    end
end