. "$PSScriptRoot/PowerManagement.ps1";
. "$PSScriptRoot/SoftwareManagement.ps1";
. "$PSScriptRoot/../../lib/Settings.ps1";
. "$PSScriptRoot/../../lib/SoftwareManagement.ps1";
. "$PSScriptRoot/../../Common/Types/InstallerAction.ps1";

<#
    .SYNOPSIS
    Deploys an action for each software selected for installation.

    .PARAMETER
    The action to execute.
#>
function Deploy-SoftwareAction {
    param(
        [System.Nullable[InstallerAction]] $Action = $null
    )

    [bool] $install = $false;
    [bool] $userInstall = $Action -eq ([InstallerAction]::ConfigureUser);
    $arguments = [hashtable]@{ };

    if ($null -ne $Action) {
        $install = ($Action -eq ([InstallerAction]::Install));
        $null = $arguments.Add("action", $Action);
    }
    else {
        $install = $true;
    }

    $hardware = Get-OSConfig "hardware";
    $collections = Get-OSConfig "software";

    # Drivers
    & {
        $driverPath = "$PSScriptRoot/../Drivers";
        $mbPath = "$driverPath/ROG Zenith Extreme Alpha";

        if ($install) {
            if ($hardware.elgatoWave) {
                if (-not (Test-ChocoPackage wavelink)) {
                    Install-ChocoPackage wavelink -ArgumentList '--install-arguments="/norestart"';
                    Remove-DesktopIcon "*Wave Link*";
                    Restart-Intermediate;
                    exit;
                }
            }
        }

        foreach ($component in $hardware.components) {
            switcH ($component) {
                ("ROG Zenith Extreme Alpha") {
                    & "$mbPath/MarvellEthernet/Main.ps1" @arguments;
                    & "$mbPath/IntelWiFi/Main.ps1" @arguments;
                    & "$mbPath/IntelBluetooth/Main.ps1" @arguments;
                    & "$mbPath/AMDChipsetX399/Main.ps1" @arguments;
                    & "$driverPath/AMDChipsetX399/Main.ps1" @arguments;
                }
                ("Predator Z301C") {
                    & "$driverPath/Predator Z301C/Main.ps1" @arguments;
                }
            }
        }

        if ($install) {
            if ($hardware.amdCPU) {
                Install-ChocoPackage amd-ryzen-master;
                $ryzenPlan = [regex]::Match("" + ((powercfg /LIST) | Where-Object { $_ -like "*(AMD Ryzen*"; }), "Power Scheme GUID: ([0-9a-f-]+) ").Groups[1].Value;

                if ($ryzenPlan) {
                    powercfg /S $ryzenPlan;
                    Backup-PowerScheme;
                }
            }

            if ($hardware.nvidiaGPU) {
                Install-ChocoPackage geforce-game-ready-driver;
                Remove-DesktopIcon "*Geforce*";
            }

            if ($hardware.corsairDevice) {
                Install-ChocoPackage icue;
            }
        }

        if ($hardware.eyeX) {
            & "$driverPath/Tobii EyeX/Main.ps1" @arguments;
        }
    };

    & {
        $softwarePath = "$PSScriptRoot/../Software";
        $commonSoftware = "$PSScriptRoot/../../Common/Software";

        # Windows Config
        & "$softwarePath/windows/Main.ps1" @arguments;

        # Driver Programs
        & "$softwarePath/lghub/Main.ps1" @arguments;
        & "$softwarePath/aliae/Main.ps1" @arguments;
        & "$softwarePath/git/Main.ps1" @arguments;
        & "$softwarePath/openssh/Main.ps1" @arguments;
        & "$softwarePath/powershell/Main.ps1" @arguments;
        & "$softwarePath/chocolatey/Main.ps1" @arguments;
        & "$softwarePath/zoxide/Main.ps1" @arguments;
        & "$commonSoftware/posh-git/Main.ps1" @arguments;
        & "$commonSoftware/terminal-icons/Main.ps1" @arguments;
        & "$softwarePath/oh-my-posh/Main.ps1" @arguments;

        if (Get-OSConfig "dualboot") {
            & "$softwarePath/ext4fsd/Main.ps1" @arguments;
        }

        # Essentials
        if ($collections.essential) {
            if ($install) {
                Install-ChocoPackage `
                    procexp `
                    procmon `
                    ;

                Install-WingetPackage `
                    KDE.KDEConnect `
                    ;
            }
        }

        # Common Software
        & "$softwarePath/winscp/Main.ps1" @arguments;
        & "$softwarePath/thunderbird/Main.ps1" @arguments;
        & "$softwarePath/putty/Main.ps1" @arguments;

        # Internet Access
        if ($install) {
            if (Test-Program "brave") {
                Install-WingetPackage Brave.Brave -ArgumentList "--scope", "machine";
                Remove-DesktopIcon "*Brave*";
                Remove-TaskbarItem "*Brave*";
            }
        }

        if ($userInstall) {
            if (Test-Program "pennywise") {
                Install-WingetPackage kamranahmedse.pennywise;
                Remove-DesktopIcon "Pennywise*";
            }
        }

        & "$softwarePath/firefox/Main.ps1" @arguments;
        & "$softwarePath/msedge-redirect/Main.ps1" @arguments;

        if ($collections.desktopExperience) {
            if ($install) {
                # Fonts
                Install-ChocoPackage nerd-fonts-CascadiaCode;

                # Tools
                Install-SetupPackage -Source "https://github.com/mRemoteNG/mRemoteNG/releases/download/2023.03.03-v1.77.3-nb/mRemoteNG-Installer-1.77.3.nb-1784.msi" -ArgumentList "/Quiet";
                Remove-DesktopIcon "mRemoteNG*";
                Install-ChocoPackage bitwarden -ArgumentList '--install-arguments="/ALLUSERS=1"';

                Install-ChocoPackage `
                    7zip `
                    gimp `
                    gpu-z `
                    windirstat `
                    winmerge `
                    handbrake `
                    hwmonitor `
                    qbittorrent `
                    imgburn `
                    inkscape `
                    krita `
                    MetaX `
                    obs-studio `
                    chocolateygui `
                    DefaultProgramsEditor `
                    keepass `
                    ;

                Remove-DesktopIcon "GIMP*";
                Remove-DesktopIcon "GPU-Z*";
                Remove-DesktopIcon "WinDirStat*";
                Remove-DesktopIcon "*HWMonitor*";
                Remove-DesktopIcon "ImgBurn*";
                Remove-DesktopIcon "InkScape*";
                Remove-DesktopIcon "Krita*";
                Remove-DesktopIcon "MetaX*";
                Remove-DesktopIcon "OBS Studio*";

                Install-WingetPackage `
                    AntSoftware.AntRenamer `
                    AppWork.JDownloader `
                    MartiCliment.UniGetUI `
                    ;

                Remove-DesktopIcon "JDownloader*";
                Remove-DesktopIcon "UniGetUI*";
            }
        }

        # ToDo: Consider hiding behind own config?
        & "$softwarePath/ubiquiti-unifi-controller/Main.ps1" @arguments;
        & "$softwarePath/nextcloud/Main.ps1" @arguments;

        if ($collections.socialMedia) {
            if ($install) {
                Install-ChocoPackage teamspeak;
                Remove-DesktopIcon "*TeamSpeak*";
            }
            elseif  ($userInstall) {
                Install-WingetPackage `
                    Element.Element `
                    OpenWhisperSystems.Signal `
                    Threema.Threema `
                    ;

                Remove-DesktopIcon "*Element*";
            }
        }

        . "$softwarePath/discord/Main.ps1" @arguments;

        if ($collections.media) {
            if ($install) {
                Install-ChocoPackage `
                    k-litecodecpackmega `
                    vlc `
                    ;

                Remove-DesktopIcon "VLC*";
                # When installing Jellyfin Media Player after iCUE, Jellyfin will try to reboot automatically
                Install-ChocoPackage jellyfin-media-player -ArgumentList "--install-args", "/norestart";
                Remove-DesktopIcon "Jellyfin Media Player*";
                Install-WingetPackage Ytmdesktop.Ytmdesktop;
                Remove-DesktopIcon "Youtube Music*";
            }
        }

        if ($collections.coding) {
            if ($install) {

                Install-ChocoPackage `
                    gh `
                    github-desktop `
                    ida-free `
                    HxD `
                    imhex `
                    dotpeek `
                    ;

                Remove-DesktopIcon "IDA *";
                Remove-DesktopIcon "GitHub*";

                if (Test-Program "docker") {
                    Install-ChocoPackage docker-desktop;
                    Remove-DesktopIcon "Docker*";
                }
            }
        }

        & "$softwarePath/vscode/Main.ps1" @arguments;
        & "$softwarePath/visualstudio/Main.ps1" @arguments;

        # Node.js
        & "$softwarePath/nvs/Main.ps1" @arguments;

        # Gaming
        if (Test-Program "steam") {
            Install-ChocoPackage `
                steam `
                -ArgumentList "--ignore-checksums" `
                ;

            Remove-DesktopIcon "*Steam*";
        }

        if ($collections.gaming) {
            if ($install) {
                Install-ChocoPackage `
                    goggalaxy `
                    epicgameslauncher `
                    rayman-controlpanel `
                    ppsspp `
                    ;

                Remove-DesktopIcon "*Epic Games*";
                Remove-DesktopIcon "*PPSSPP *-Bit*";

                Install-ChocoPackage `
                    ubisoft-connect `
                    -ArgumentList "--ignore-checksums" `
                    ;

                Remove-DesktopIcon "*Ubisoft Connect*";

                Install-WingetPackage ElectronicArts.EADesktop;
                Remove-DesktopIcon "EA.*";
            }
        }

        & "$softwarePath/tm-nations-forever/Main.ps1" @arguments;
        & "$softwarePath/tm-united-forever/Main.ps1" @arguments;
        & "$softwarePath/maniaplanet/Main.ps1" @arguments;
        & "$softwarePath/osu!/Main.ps1" @arguments;
        & "$softwarePath/osu!lazer/Main.ps1" @arguments;
        & "$softwarePath/retroarch/Main.ps1" @arguments;
        & "$softwarePath/rewasd/Main.ps1" @arguments;
    };
}