#!/bin/pwsh
. "$PSScriptRoot/../Scripts/Prerequisites.ps1";

. "$PSScriptRoot/Manage.ps1";
. "$PSScriptRoot/Upgrade.ps1";
. "$PSScriptRoot/User/Install.ps1";
. "$PSScriptRoot/../Scripts/Context.ps1";
. "$PSScriptRoot/../Software/Firefox/Install.ps1";

function Invoke-WindowsInstallation([Context] $context)
{
    $Global:InformationPreference = "Continue";
    $Global:ErrorActionPreference = "Inquire";
    $context.UserNames ??= @("Manuel");
    Start-WindowsInstallation $context;
}

function Start-WindowsInstallation([Context] $context) {
    $finished = $false;
    Remove-Item Env:\POSH_THEME -ErrorAction SilentlyContinue;
    $configPath = "$PSScriptRoot/../Config";
    $softwarePath = "$PSScriptRoot/../Software";
    $initialConfigStage = "InitialConfiguration";
    $prerequisitesStage = "InstallationPrerequisites";
    $driverStage = "DriverInstallation";
    $softwareStage = "MachineWideSoftwareInstallation";
    $userStage = "CreatingUser";
    $restorationStage = "Restoring";


    while (-not $finished) {
        switch ($context.GetStage()) {
            { (-not $_) -or ($_ -eq $initialConfigStage) } {
                $context.SetStage($initialConfigStage);

                if ((Get-Command Initialize-Configuration -ErrorAction SilentlyContinue)) {
                    Write-Information "Configuration initialization function was found. Running...";
                    Initialize-Configuration $context;
                }

                $null = Enable-WindowsOptionalFeature -Online -All -FeatureName "NetFx3";

                . "$configPath/Windows/Install.ps1" $context;
                . "$configPath/Explorer/Install.ps1" $context;
                . "$configPath/OpenSSH/Install.ps1" $context;
                . "$configPath/chocolatey/Install.ps1";

                $context.RemoveDesktopIcon("*Microsoft Edge*");
                $context.SetStage($prerequisitesStage);
                break;
            }
            # Always install updates
            default {
                Write-Host "Starting Installation and Restoration of Windows";
                Update-WindowsInstallation $context;
            }
            $prerequisitesStage {
                Write-Host "Installing prerequisites for installing software";

                if (-not $(Get-Command winget)) {
                    choco install -y winget;
                }

                Install-Module -AcceptLicense -Force "NuGet";
                Import-Module NuGet;

                Install-Firefox $context;
                choco install -y selenium-gecko-driver;
                $null = Install-Package -Force Selenium.WebDriver -RequiredVersion 4.10.0 -SkipDependencies;

                winget install --accept-source-agreements --accept-package-agreements -e --id AutoHotkey.AutoHotkey;

                $context.SetStage($driverStage);
                break;
            }
            $driverStage {
                Write-Host "Installing drivers";

                if ((Get-Command Install-PortValhallaDrivers -ErrorAction SilentlyContinue)) {
                    Write-Information "Driver installation function was found. Starting installation";
                    Install-PortValhallaDrivers $context;
                }

                Write-Information "Finished installing drivers";
                $context.SetStage($softwareStage);
                $context.Reboot();
                exit;
            }
            $softwareStage {
                Write-Host "Setting up software with default app associations";
                . "$softwarePath/WinSCP/Install.ps1" $context;
                . "$softwarePath/Thunderbird/Install.ps1" $context;

                Write-Host "Installing default settings for new users";
                . "$softwarePath/aliae/Install.ps1" $context;
                . "$softwarePath/posh-git/Install.ps1";
                . "$softwarePath/Terminal-Icons/Install.ps1";
                . "$softwarePath/Oh My Posh/Install.ps1" $context;
                $context.SetStage($userStage);
                break;
            }
            $userStage {
                Install-PersonalUsers $context;
                $context.SetStage($restorationStage);
                break;
            }
            $restorationStage {
                Restore-WindowsInstallation $context;
                $finished = $true;
                break;
            }
        }
    }
}