# This script updates (if this script is run from a folder where Echosync is already present) or "install" Echosync
# Version 2.1 (2019-03-13)
# Copyright Sylvain Rougeaux, 2018-2019, www.luminescence-software.org

param([string] $scriptFolder = "?")
$ErrorActionPreference = "Stop"

$scriptBlock = 
{

param([string] $echosyncFolder)

$culture = (Get-UICulture).TwoLetterISOLanguageName
if ($culture -eq "fr")
{
    $DownloadingEchosync = "Téléchargement d'Echosync depuis le site web Luminescence Software..."
    $ScriptRootNotIdentified = "Le répertoire dans lequel Echosync doit être installé ou mis à jour n'a pas pu être identifié."
    $WaitingForEchosyncClosing = "En attente de la fermeture d'Echosync..."
    $EchosyncClosed = "Echosync a été fermé."
    $EchosyncDownloaded = "Echosync a été téléchargé avec succès."
    $InvalidZipFile = "L'archive zip d'Echosync n'est pas valide car elle ne contient pas de répertoire racine."
    $EchosyncUpdating = "Echosync est prêt à être mis à jour."
    $EchosyncExtracting = "Décompression des données de l'archive zip d'Echosync..."
    $EchosyncUpdated = "Echosync a été mis à jour avec succès dans '{0}'."
    $PreviousInstallationLocation = "L'installation précédente a été conservée dans '{0}'. Vous pourrez supprimer ce répertoire si vous êtes satisfait de la dernière version."
    $EchosyncInstalling = "Echosync est prêt à être installé."
    $EchosyncFolderAlreadyExists = "L'archive zip d'Echosync ne peut être extraite dans '{0}' car un dossier nommé '{1}' y est déjà présent."
    $EchosyncInstalled = "Echosync a été installé avec succès dans '{0}'."
    $EchosyncReadyToStart = "Vous pouvez maintenant démarrer Echosync en lançant 'Echosync.exe' ou 'EchosyncLauncher.exe' (si vous souhaitez pouvoir choisir facilement si Echosync doit démarrer avec des droits d'administration)."
    $WaitingForReleasingEchosyncFolder = "L'accès au dossier d'Echosync est refusé par un ou plusieurs processus. Merci de fermer tous les processus susceptibles d'utiliser ce dossier avant de poursuivre la mise à jour."
}
elseif ($culture -eq "it")
{
    $DownloadingEchosync = "Download di Echosync dal sito di Luminescence Software in corso..."
    $ScriptRootNotIdentified = "La cartella di installazione di Echosync non può essere trovata."
    $WaitingForEchosyncClosing = "Chiusura di Echosync in corso..."
    $EchosyncClosed = "	Echosync è stato chiuso."
    $EchosyncDownloaded = "Echosync è stato scaricato con successo."
    $InvalidZipFile = "L'archivio zip di Echosync non è valido perché non contiene alcuna cartella di root."
    $EchosyncUpdating = "Echosync è pronto per essere aggiornato."
    $EchosyncExtracting = "Estrazione dei dati dall'archivio zip di Echosync..."
    $EchosyncUpdated = "Echosync è stato aggiornato con successo in '{0}'."
    $PreviousInstallationLocation = "Una precedente installazione è stata conservata in '{0}'. Puoi eliminare questa cartella se ti stai trovando bene con l'ultima versione."
    $EchosyncInstalling = "Echosync è pronto per essere installato."
    $EchosyncFolderAlreadyExists = "L'archivio zip di Echosync non può essere estratto in '{0}' perché una cartella chiamata '{1}' già esiste in quel percorso."
    $EchosyncInstalled = "Echosync è stato installato con successo in '{0}'."
    $EchosyncReadyToStart = "Ora puoi avviare Echosync eseguendo 'Echosync.exe' o 'EchosyncLauncher .exe' (se vuoi essere in grado di scegliere se Echosync deve aprirsi come amministratore)."
    $WaitingForReleasingEchosyncFolder = "L'accesso alla cartella di Echosync è negato da uno o più processi. Per favore, chiudi tutti i processi che potrebbero utilizzare questa cartella prima di procedere con l'aggiornamento."
}
elseif ($culture -eq "es")
{
    $DownloadingEchosync = "Descargando Echosync desde el sitio web de Luminescence Software..."
    $ScriptRootNotIdentified = "La carpeta en la cual Echosync debería ser instalado o actualizado puede no estar identificada."
    $WaitingForEchosyncClosing = "Esperando que Echosync se cierre..."
    $EchosyncClosed = "Echosync se ha cerrado."
    $EchosyncDownloaded = "Echosync ha sido descargado correctamente."
    $InvalidZipFile = "El archivo zip de Echosync no es válido porque no contiene ninguna carpeta raíz."
    $EchosyncUpdating = "Echosync está listo para ser actualizado."
    $EchosyncExtracting = "Extrayendo datos desde el archivo zip de Echosync..."
    $EchosyncUpdated = "Echosync ha sido actualizado con éxito en '{0}'."
    $PreviousInstallationLocation = "La instalación anterior se ha mantenido en '{0}'. Puede eliminar esta carpeta si está satisfecho con la última versión."
    $EchosyncInstalling = "Echosync está listo para ser instalado."
    $EchosyncFolderAlreadyExists = "El archivo zip de Echosync no se puede extraer en '{0}' porque ya hay una carpeta llamada '{1}'."
    $EchosyncInstalled = "Echosync se ha instalado con éxito en '{0}'."
    $EchosyncReadyToStart = "Ahora puede iniciar Echosync ejecutando 'Echosync.exe' o 'EchosyncLauncher.exe' (si desea poder elegir fácilmente si Echosync debe comenzar con derechos administrativos)."
    $WaitingForReleasingEchosyncFolder = "El acceso a la carpeta Echosync está denegado por uno o más procesos. Cierre todos los procesos que puedan usar esta carpeta antes de continuar con la actualización."
}
elseif ($culture -eq "de")
{
    $DownloadingEchosync = "Echosync wird von Luminescence Software heruntergeladen..."
    $ScriptRootNotIdentified = "Der Installationsordner für Echosync wurde nicht gefunden."
    $WaitingForEchosyncClosing = "Warten auf Beenden von Echosync..."
    $EchosyncClosed = "Echosync wurde beendet."
    $EchosyncDownloaded = "Echosync wurde erfolgreich heruntergeladen."
    $InvalidZipFile = "Das Echosync zip Archiv ist ungültig, da es keinen Quellordner enthält."
    $EchosyncUpdating = "Echosync kann upgedated werden."
    $EchosyncExtracting = "Extraktion des Echosync zip Archivs..."
    $EchosyncUpdated = "Echosync wurde in '{0}' erfolgreich upgedated."
    $PreviousInstallationLocation = "Die vorherige Installation wurde in '{0}' belassen. Sie können diesen Ordner löschen, wenn Sie mit der neuesten Version zufrieden sind."
    $EchosyncInstalling = "Echosync kann nun installiert werden."
    $EchosyncFolderAlreadyExists = "Echosync kann nicht nach '{0}' extrahiert werden, da dort bereits ein Ordner '{1}' existiert."
    $EchosyncInstalled = "Echosync wurde erfolgreich in '{0}' installiert."
    $EchosyncReadyToStart = "Sie können nun Echosync starten mit 'Echosync.exe' oder 'EchosyncLauncher;exe' (wenn Sie mit Administratorrechten starten möchten)."
    $WaitingForReleasingEchosyncFolder = "Der Zugriff auf den Echosync-Ordner wird von einem oder mehreren Prozessen blockiert. Bitte schliessen sie alle Prozesse vor der Fortsetzung des Updates."
}
else
{
    $DownloadingEchosync = "Downloading Echosync from the Luminescence Software website..."
    $ScriptRootNotIdentified = "The folder in which Echosync should be installed or updated could not be identified."
    $WaitingForEchosyncClosing = "Waiting for Echosync closing..."
    $EchosyncClosed = "Echosync has been closed."
    $EchosyncDownloaded = "Echosync has been successfully downloaded."
    $InvalidZipFile = "The Echosync zip archive is not valid because it doesn't contain any root folder."
    $EchosyncUpdating = "Echosync is ready to be updated."
    $EchosyncExtracting = "Extracting data from the Echosync zip archive..."
    $EchosyncUpdated = "Echosync has been successfully updated in '{0}'."
    $PreviousInstallationLocation = "Previous installation has been kept in '{0}'. You can delete this folder if you are satisfied with the latest version."
    $EchosyncInstalling = "Echosync is ready to be installed."
    $EchosyncFolderAlreadyExists = "The Echosync zip archive can not be extracted in '{0}' because a folder named '{1}' is already there."
    $EchosyncInstalled = "Echosync has been successfully installed in '{0}'."
    $EchosyncReadyToStart = "You can now start Echosync by running 'Echosync.exe' or 'EchosyncLauncher.exe' (if you want to be able to easily choose if Echosync should start with administrative rights)."
    $WaitingForReleasingEchosyncFolder = "The access to the Echosync folder is denied by one or more processes. Please close all processes that may use this folder before continuing the update."
}

if (-not (Test-Path -Path $echosyncFolder -PathType Container))
{
    Write-Host $ScriptRootNotIdentified -ForegroundColor Red
    return
}

Add-Type -Assembly "System.IO.Compression.FileSystem"
Function GetUniqueRootFolder([string] $zipPath)
{
    $zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
    try 
    {
        if ($zip.Entries.Count -eq 0) { return $null }
        $firstEntry = $zip.Entries[0].FullName
        foreach ($entry in $zip.Entries) {
            if (-not $entry.FullName.StartsWith($firstEntry)) { return $null }
        }

        return $firstEntry.TrimEnd('/')
    }
    finally 
    {
        $zip.Dispose()
    }
}

Function WaitForEchosyncToExit()
{
    $echosyncProcess = Get-Process -Name "Echosync" -ErrorAction SilentlyContinue
    if ($null -ne $echosyncProcess)
    {
        Write-Host $WaitingForEchosyncClosing -ForegroundColor Yellow
        $echosyncProcess | Foreach-Object { $_.CloseMainWindow() | Out-Null }
        Wait-Process -InputObject $echosyncProcess
        Write-Host $EchosyncClosed
    }
}

Write-Host $DownloadingEchosync
$downloadUrl = "http://www.luminescence-software.org/download/echosync/Echosync.zip"
$installerZip = Join-Path -Path $env:TEMP -ChildPath "Echosync.zip"
Invoke-WebRequest -Uri $downloadUrl -OutFile $installerZip
Write-Host $EchosyncDownloaded

$rootFolder = GetUniqueRootFolder $installerZip
if ($null -eq $rootFolder)
{
    Write-Host $InvalidZipFile -ForegroundColor Red
    return
}

$echosyncExe = Join-Path -Path $echosyncFolder -ChildPath "Echosync.exe"
if (Test-Path -Path $echosyncExe -PathType Leaf)
{
    Write-Host $EchosyncUpdating

    $oldProfilesPath = Join-Path -Path $echosyncFolder -ChildPath "Profiles"
    $hasProfiles = Test-Path -Path $oldProfilesPath -PathType Container
    if ($hasProfiles) { WaitForEchosyncToExit }

    $echosyncParentFolder = Split-Path $echosyncFolder -Parent
    $newEchosyncFolder = Join-Path -Path $echosyncParentFolder -ChildPath $rootFolder
    $oldEchosyncFolder = $echosyncFolder

    if (Test-Path -Path $newEchosyncFolder -PathType Container)
    {
        $oldEchosyncFolder = "$newEchosyncFolder ($((Get-Date).Ticks))"
        while ($true)
        {
            try
            {
                Rename-Item -Path $newEchosyncFolder -NewName $oldEchosyncFolder -Force
                $oldProfilesPath = Join-Path -Path $oldEchosyncFolder -ChildPath "Profiles"
                break
            }
            catch [System.IO.IOException]
            {
                Write-Host $WaitingForReleasingEchosyncFolder -ForegroundColor Yellow
                Pause
            }
        }
    }
    
    Write-Host $EchosyncExtracting
    [System.IO.Compression.ZipFile]::ExtractToDirectory($installerZip, $echosyncParentFolder)

    if ($hasProfiles) { Copy-Item -Path $oldProfilesPath -Recurse -Destination $newEchosyncFolder -Container }

    Write-Host ($EchosyncUpdated -f $newEchosyncFolder)
    Write-Host ($PreviousInstallationLocation -f $oldEchosyncFolder)
}
else 
{
    Write-Host $EchosyncInstalling

    $newEchosyncFolder = Join-Path -Path $echosyncFolder -ChildPath $rootFolder
    if (Test-Path -Path $newEchosyncFolder -PathType Container)
    {
        Write-Host ($EchosyncFolderAlreadyExists -f $echosyncFolder, $rootFolder) -ForegroundColor Red
        return
    }

    Write-Host $EchosyncExtracting
    [System.IO.Compression.ZipFile]::ExtractToDirectory($installerZip, $echosyncFolder)
    
    Write-Host ($EchosyncInstalled -f $newEchosyncFolder)
}

Remove-Item $installerZip -ErrorAction SilentlyContinue

Write-Host $EchosyncReadyToStart
Set-Location -Path $newEchosyncFolder
Start-Process -FilePath $newEchosyncFolder

}

if ((Get-Host).Version.Major -le 2)
{
    Write-Host "This script requires PowerShell v3 or later." -ForegroundColor Red
    Read-Host -Prompt "Press Enter to continue..." # "Pause" is not supported in PowerShell v2
    return
}

$tempPath = [System.IO.Path]::GetTempPath().TrimEnd('\')
if ($PSScriptRoot.StartsWith($tempPath) -eq $false)
{
    Set-Location -Path "C:\"
    Copy-Item -Path $PSCommandPath -Destination $tempPath -Force
    $scriptPath = Join-Path -Path $tempPath -ChildPath (Split-Path $PSCommandPath -Leaf)
    Start-Process -FilePath "powershell.exe" -ArgumentList "-NoExit -NoLogo -ExecutionPolicy Bypass -File `"$scriptPath`" `"$PSScriptRoot`""
    [Environment]::Exit(0)
}

Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $scriptFolder