<#
.SYNOPSIS
    SilentProdInstallApp.ps1 - Install or uninstall an application without an interaction with an operator for production, on a Fujifilm multifunction device using addonAppTool.exe.

.DESCRIPTION
    This script installs or uninstalls an application on a Fujifilm multifunction device.
    It expects credentials, device information, and action as parameters.
    It searches for *_Installer.zip in the current directory, extracts it,
    and executes addonAppTool.exe with the provided parameters.

.PARAMETER Action
    [Required] Operation to perform. Must be either:
        --install   → Installs or overwrites the application.
        --uninstall → Uninstalls the application.
    - Alias: -act

.PARAMETER Username
    [Required] Administrator username of the target device.
	- Alias: -u

.PARAMETER Password
    [Required] Administrator password of the target device.
    - Alias: -p

.PARAMETER DeviceAddress
    [Required] IP Address or Hostname of the target Fuji device.
    - Alias: -mfp

.PARAMETER DeviceId
    [Required for --install only] Unique identifier of the target Fujifilm device (used to build the service URL).
    - Alias: -id
    - Must be provided and non-empty.

.PARAMETER ServerAddress
    [Required for --install only] Root address of the target server (without path).
    - Alias: -srv
    - The script automatically appends required internal paths and the DeviceId to build the final URL.
	- The script automatically appends "?id=<DeviceId>" to build the final URL.
    - Example:
        ServerAddress = http://myserver.com
        DeviceId      = ABC123
        -> Final URL  = http://myserver.com/custom/service?id=ABC123

.PARAMETER DebugLogFile
    [Optional] Path to a debug log file for addonAppTool.exe output.
    - Alias: -log
#>
param(
    [Alias("act")]
    [string]$Action,

    [Alias("u")]
    [string]$Username,

    [Alias("p")]
    [string]$Password,

    [Alias("mfp")]
    [string]$DeviceAddress,

    [Alias("id")]
    [string]$DeviceId,

    [Alias("srv")]
    [string]$ServerAddress,

    [Alias("log")]
    [string]$DebugLogFile
)

# ------------------------------
# Global variable
# ------------------------------
$isInstall = ($Action -eq "--install")

# ------------------------------
# Logging helpers
# ------------------------------
function Write-InstallAppLog {
    param([string]$Message)

	if($isInstall){
		Write-Host "[INSTALL] $Message"
	}else{
		Write-Host "[UNINSTALL] $Message"
	}

}

function Write-InstallAppError {
    param([string]$Message)

	if($isInstall){
		Write-Host "[INSTALL] ERROR: $Message" -ForegroundColor Red
	} else {
		Write-Host "[UNINSTALL] ERROR: $Message" -ForegroundColor Red
	}
}

# ------------------------------
# Paths
# ------------------------------
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$guid = ((Get-Date -Format "yyyyMMddHHmmssfff") + "_" + (Get-Random -Maximum 1000000))
$installWorkDir = Join-Path $scriptDir ("InstallAppWorkDir_" + ($DeviceId) + "_" + ($guid))

Write-Host "`n=== Starting Fujifilm Application Installer Script ==="

# ------------------------------
# Main execution with error handling
# ------------------------------
try {
    # Validate action
    if (-not $Action) { throw "Missing required parameter: -Action (--install or --uninstall)" }
    if (($Action -ne "--install") -and ($Action -ne "--uninstall")) { throw "Invalid -Action. Must be --install or --uninstall" }
    if (-not $Username)     { throw "Missing required parameter: -Username" }
    if (-not $Password)     { throw "Missing required parameter: -Password" }
    if (-not $DeviceAddress){ throw "Missing required parameter: -DeviceAddress" }

    if ($Action -eq "--install") {
        if (-not $DeviceId) { throw "Missing required parameter: -DeviceId for install" }
        if (-not $ServerAddress) { throw "Missing required parameter: -ServerAddress for install" }
    }

    Write-InstallAppLog "Processing MFP $DeviceAddress"

    # Clean working directory
    if (Test-Path $installWorkDir) {
        Remove-Item -Path $installWorkDir -Recurse -Force
    }
    New-Item -ItemType Directory -Path $installWorkDir | Out-Null

    # Locate installer zip
    $installerZip = Get-ChildItem -Path $scriptDir -Filter "*_Installer.zip" -File | Select-Object -First 1
    if (-not $installerZip) { throw "No *_Installer.zip found in current directory." }

    # Extract installer
    Expand-Archive -Path $installerZip.FullName -DestinationPath $installWorkDir -Force

    # Locate addonAppTool.exe
    $exePath = Join-Path $installWorkDir "installer\lib\addonAppTool.exe"
    if (-not (Test-Path $exePath)) { throw "addonAppTool.exe not found in extracted installer." }

    # ------------------------------
    # Build arguments
    # ------------------------------
    $exeArgs = @(
        "-u", $Username,
        "-p", $Password
    )

    if ($Action -eq "--install") {
        $exeArgs += "--install"
        if ($ServerAddress) {
            $relativePath = "/embedded/fujifilm/boot.xhtml"
            $finalUrl = "${ServerAddress}${relativePath}?id=${DeviceId}"
            $exeArgs += "--url"; $exeArgs += $finalUrl
        }
    }
    elseif ($Action -eq "--uninstall") {
        $exeArgs += "--uninstall"
    }

    if ($DebugLogFile) { $exeArgs += "-d"; $exeArgs += $DebugLogFile }
    $exeArgs += $DeviceAddress

    # ------------------------------
    # Execute addonAppTool.exe
    # ------------------------------
    Write-InstallAppLog "Executing addonAppTool.exe for $DeviceAddress..."
    & $exePath $exeArgs
    if ($LASTEXITCODE -ne 0) { throw "addonAppTool.exe failed with exit code $LASTEXITCODE" }

    Write-InstallAppLog "$Action completed successfully for $DeviceAddress"

    exit 0

} catch {
    Write-InstallAppError $_
    exit 1
} finally {
    if (Test-Path $installWorkDir) {
        Write-InstallAppLog "Cleaning up $installWorkDir ... "
        Remove-Item -Path $installWorkDir -Recurse -Force
    }
}
