param(
    $Action,
    [hashtable] $Arguments
)

& {
    param($parameters)

    . "$PSScriptRoot/../../Scripts/Restoration.ps1";
    . "$PSScriptRoot/../../Scripts/SoftwareManagement.ps1";
    . "$PSScriptRoot/../../../Common/Scripts/BrowserAutomation.ps1";
    . "$PSScriptRoot/../../../Common/Scripts/Software.ps1";
    . "$PSScriptRoot/../../../Common/Scripts/SoftwareManagement.ps1";
    . "$PSScriptRoot/../../../Common/Scripts/System.ps1";

    [System.Tuple[string, string, string][]] $versions = @(
        [System.Tuple]::Create("visualstudio2019enterprise", "VisualStudio.16.Release", "Microsoft.VisualStudio.Product.Enterprise"),
        [System.Tuple]::Create("visualstudio2019community", "VisualStudio.16.Release", "Microsoft.VisualStudio.Product.Community"),
        [System.Tuple]::Create("visualstudio2022enterprise", "VisualStudio.17.Release", "Microsoft.VisualStudio.Product.Enterprise"),
        [System.Tuple]::Create("visualstudio2022community", "VisualStudio.17.Release", "Microsoft.VisualStudio.Product.Community")
    );

    <#
        .SYNOPSIS
        Gets the path to the Visual Studio Installer.
    #>
    function Get-InstallerPath {
        return "$((Get-KnownFolder ProgramFilesX86).Path)/Microsoft Visual Studio/Installer/vs_installer.exe";
    }

    <#
        .SYNOPSIS
        Gets the path to the configuration file in the backup archive.

        .PARAMETER PackageName
        The name of the package to get the configuration for.
    #>
    function Get-ConfigPath {
        param(
            [string] $Name,
            [string] $PackageName
        )

        return Join-Path "$Name" "$PackageName.vsconfig";
    }

    Start-SoftwareInstaller @parameters `
        -Backup {
            param([string] $Name)

            foreach ($version in $versions) {
                if (Test-ChocoPackage $version[0]) {
                    Write-Host "Backing up ``$($version[0])…";
                    $configFile = New-TemporaryFile;

                    Start-Process -FilePath (Get-InstallerPath) -Wait `
                        -ArgumentList @(
                            "export",
                            "--channelId", $version[1],
                            "--productId", $version[2],
                            "--config", $configFile,
                            "--quiet"
                        );

                    Add-BackupArtifacts -Source $configFile -Path (Get-ConfigPath $Name $version[0]);
                    Remove-Item $configFile;
                }
            }
        } `
        -Installer {
            param([string] $Name)

            foreach ($version in $versions) {
                $packageName = $version[0];
                $file = New-TemporaryFile;
                Remove-Item $file;
                Expand-BackupArtifacts -Path (Get-ConfigPath $Name $packageName) -Target $file;

                if (Test-Path $file) {
                    Write-Host "Restoring ``$packageName``…";
                    Install-ChocoPackage $packageName -ArgumentList "--params","--config `"$file`"";
                }
            }

            Remove-DesktopIcon "CocosCreator*";
            Remove-DesktopIcon "Unity Hub*";
        };
} $PSBoundParameters;