. "$PSScriptRoot/../../../lib/Software.ps1";
. "$PSScriptRoot/../../../lib/System.ps1";
. "$PSScriptRoot/../../Types/InstallerAction.ps1";

& {
    $configure = {
        param(
            [string] $User
        )

        $getConfig = $null;

        if ($User) {
            $getConfig = { Get-UserConfig -UserName $User @args };
            $sudoArgs = @("-u", $User);
            $configArgs = @("--global");
        }
        else {
            $getConfig = { Get-OSConfig @args };
            $sudoArgs = @();
            $configArgs = @("--system");
        }

        $config = & $getConfig "programs.git";

        <#
            .SYNOPSIS
            Sets a configuration option in git.
        #>
        function Set-GitConfig {
            sudo @sudoArgs git config @configArgs @args;
        }

        if ((-not $IsWindows) -or $User) {
            $branch = $config.defaultBranch;

            if ($branch) {
                Set-GitConfig "init.defaultBranch" $branch;
            }
        }

        if ($User) {
            $displayName = & $getConfig "displayName";
            $mailAddress = & $getConfig "mailAddress";

            if ($displayName) {
                Set-GitConfig "user.name" $displayName;
            }

            if ($mailAddress) {
                Set-GitConfig "user.email" $mailAddress;
            }
        }

        # Git Flow
        . {
            $dir = New-TemporaryDirectory;
            $key = "flow";
            $mainBranch = $config."$key".mainBranch;
            $devBranch = $config."$key".devBranch;

            & {
                git -C "$dir" init;
                git -C "$dir" config user.name "PortValhalla";
                git -C "$dir" config user.email "no-reply@valhal.la";
                git -C "$dir" commit --allow-empty -m "Initial commit";
                git -C "$dir" branch master;
                git -C "$dir" branch dev;
                git -C "$dir" flow init --defaults;
            } | Out-Null;

            if ($mainBranch) {
                git -C "$dir" branch $mainBranch | Out-Null;
                sudo @sudoArgs git -C "$dir" flow config set @configArgs master $mainBranch;
            }

            if ($devBranch) {
                git -C "$dir" branch $devBranch | Out-Null;
                sudo @sudoArgs git -C "$dir" flow config set @configArgs develop $devBranch;
            }

            Remove-Item -Recurse -Force $dir;
        };

        # Aliases
        [PSCustomObject] $aliases = $config.aliases;

        if ($aliases) {
            foreach ($alias in ($aliases | Get-Member -MemberType Properties)) {
                Set-GitConfig "alias.$($alias.Name)" $aliases.$($alias.Name);
            }
        }
    };

    Start-SoftwareInstaller @args `
        -Configurator {
            & $configure @args;
        } `
        -UserConfigurator {
            param(
                [hashtable] $Arguments
            )

            & $configure -User $Arguments.Name;
        };
} @args;