# This script updates (if this script is run from a folder where Echosync is already present) or "installs" Echosync
# Version 2.4 (2020-10-16)
# Copyright Sylvain Rougeaux, 2018-2020, 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)."
    $FolderAccessDenied = "Assurez-vous d'avoir fermé tous les processus utilisant ce chemin, et de disposer des droits suffisants pour écrire dans ce chemin, avant de réessayer."
    $AbortRetryQuestion = "Appuyez sur 'A' pour abandonner ou toute autre touche pour réessayer"
}
elseif ($culture -eq "it")
{
    # Italian translations provided by Fabio Biocchetti
    $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)."
    $FolderAccessDenied = "Assicurati di aver chiuso tutti i processi che usano questo percorso, e di avere sufficienti diritti di scrittura, prima di riprovare."
    $AbortRetryQuestion = "Premi 'A' per annullare o qualsiasi altro tasto per riprovare"
}
elseif ($culture -eq "es")
{
    # Spanish translations provided by Javier Tapia Torres
    $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)."
    $FolderAccessDenied = "Asegúrese de haber cerrado todos los procesos que utilizan esta ruta y de tener derechos insuficientes para escribir en esta ruta, antes de intentarlo de nuevo."
    $AbortRetryQuestion = "Pulse 'A' para anular o cualquier otra tecla para reintentar"
}
elseif ($culture -eq "de")
{
    # German translations provided by Roger Taouss-Schirmer
    $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)."
    $FolderAccessDenied = "Verlassen Sie alle Prozesse, die diesen Weg benutzen und vergewissern Sie sich, dass Sie autorisiert sind diesen Weg zu benutzen bevor Sie es erneut versuchen."
    $AbortRetryQuestion = "Geben Sie 'A' ein um abzubrechen oder drücken Sie irgendeine andere Taste um erneut zu versuchen"
}
elseif ($culture -eq "ru")
{
    # Russian translations provided by Jyrkka Teterev
    $DownloadingEchosync = "Скачивание Echosync с веб-сайта Luminescence Software..."
    $ScriptRootNotIdentified = "Папка, в которой Echosync должен быть установлен или обновлён, не может быть идентифицирована."
    $WaitingForEchosyncClosing = "Ожидание закрытия Echosync..."
    $EchosyncClosed = "Echosync был закрыт."
    $EchosyncDownloaded = "Echosync был успешно скачан."
    $InvalidZipFile = "ZIP-архив Echosync недействителен, поскольку в нём нет корневой папки."
    $EchosyncUpdating = "Echosync готов к обновлению."
    $EchosyncExtracting = "Извлечение данных из ZIP-архива Echosync..."
    $EchosyncUpdated = "Echosync был успешно обнавлён в '{0}'."
    $PreviousInstallationLocation = "Предыдущая установка была сохранена в '{0}'. Вы можете удалить эту папку, если вас устраивает последняя версия."
    $EchosyncInstalling = "Echosync готов к установке."
    $EchosyncFolderAlreadyExists = "Не удалось распаковать ZIP-архив Echosync в '{0}', поскольку папка с именем '{1}' уже существует."
    $EchosyncInstalled = "Echosync был успешно установлен в '{0}'."
    $EchosyncReadyToStart = "Теперь вы можете запустить Echosync, запустив 'Echosync.exe' или 'EchosyncLauncher.exe' (если вы хотите легко запускать Echosync с правами администратора)."
    $FolderAccessDenied = "Перед повторной попыткой убедитесь, что вы закрыли все процессы, использующие этот путь, и имеете достаточные права для записи по этому пути."
    $AbortRetryQuestion = "Нажмите 'A' для отмены или любую другую клавишу для повторной попытки"
}
elseif ($culture -eq "zh")
{
    # Chinese translations provided by 王晨旭
    $DownloadingEchosync = "从 Luminescence 网站下载 Echosync..."
    $ScriptRootNotIdentified = "无法确定应在其中安装或更新 Echosync 的文件夹。"
    $WaitingForEchosyncClosing = "等待 Echosync 关闭..."
    $EchosyncClosed = "Echosync 已关闭。"
    $EchosyncDownloaded = "Echosync 下载已成功。"
    $InvalidZipFile = "Echosync zip 存档无效，因为它不包含任何根文件夹。"
    $EchosyncUpdating = "Echosync 已准备好进行更新。"
    $EchosyncExtracting = "从 Echosync zip 存档中提取数据..."
    $EchosyncUpdated = "Echosync 已成功在 '{0}' 中更新。"
    $PreviousInstallationLocation = "以前的安装已保存在 '{0}' 中。 如果您对最新版本满意，可以删除此文件夹。"
    $EchosyncInstalling = "Echosync 已准备好安装。"
    $EchosyncFolderAlreadyExists = "无法在 '{0}' 中提取 Echosync zip 存档，因为已经存在名为 '{1}' 的文件夹。"
    $EchosyncInstalled = "Echosync 已成功安装在 '{0}' 中。"
    $EchosyncReadyToStart = "现在，您可以通过运行 'Echosync.exe' 或 'EchosyncLauncher.exe' 来启动Echosync（如果您希望是否应以管理权限运行 Echosync）。"
    $FolderAccessDenied = "在重试之前，请确保已关闭使用此路径的所有进程，并具有足够的权限来写入此路径。"
    $AbortRetryQuestion = "按 'A' 放弃或按其他任何键重试"
}
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)."
    $FolderAccessDenied = "Make sure you have closed all processes using this path, and have sufficient rights to write to this path, before trying again."
    $AbortRetryQuestion = "Press 'A' to abort or any other key to retry" 
}

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

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
    }
}

Function TryRenameFolder([string] $path, [string] $newPath)
{
    while ($true)
    {
        try
        {
            Rename-Item -Path $path -NewName $newPath -Force
            return $true
        }
        catch
        {
            Write-Host $_.Exception.Message -ForegroundColor Red
            Write-Host $FolderAccessDenied -ForegroundColor Yellow
            
            $response = Read-Host -Prompt $AbortRetryQuestion
            if ($response -eq "a") { return $false }
        }
    }
}

Function TryExtractZip([string] $zipPath, [string] $destinationPath)
{
    try 
    {
        [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $destinationPath)
        return $true
    }
    catch 
    {
        Write-Host $_.Exception.GetBaseException().Message -ForegroundColor Red
        return $false
    }
}

Function Quit()
{
    Set-Location -Path $echosyncFolder
    exit
}

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
    Quit
}

$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}_backup_$((Get-Date).Ticks)"
        if ((TryRenameFolder $newEchosyncFolder $oldEchosyncFolder) -ne $true) { Quit }
        $oldProfilesPath = Join-Path -Path $oldEchosyncFolder -ChildPath "Profiles"
    }
    
    Write-Host $EchosyncExtracting
    if ((TryExtractZip $installerZip $echosyncParentFolder) -ne $true) { Quit }

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

    Write-Host ($EchosyncUpdated -f $newEchosyncFolder) -ForegroundColor Green
    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
        Quit
    }

    Write-Host $EchosyncExtracting
    if ((TryExtractZip $installerZip $echosyncFolder) -ne $true) { Quit }
    
    Write-Host ($EchosyncInstalled -f $newEchosyncFolder) -ForegroundColor Green
}

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
    exit
}

$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