#!/usr/bin/pwsh

param(
    [Alias('h')][switch]$ShowHelp,
    [Alias('m')][string]$HomeDir=""
)

if ($ShowHelp) {
    Write-Host "DESCRIPTION: Uninstall Anypoint Monitoring OpenTelemetry Collector"
    Write-Host "Usage: .\$($MyInvocation.MyCommand) [options]"
    Write-Host " "
    Write-Host "Options:"
    Write-Host "-h,       Show help"
    Write-Host "-m [DIR]  Set home directory - defaults to MULE_HOME"
    Write-Host " "
    exit 0
}

if (-not $HomeDir -or -not (Test-Path $HomeDir)) {
    if ($env:MULE_HOME -and (Test-Path $env:MULE_HOME)) {
        $HomeDir = $env:MULE_HOME
    } else {
        $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
        $HomeDir = (Resolve-Path -Path (Join-Path -Path $scriptDir -ChildPath "..\..")).Path
        Write-Host "Determined the MULE_HOME"
    }
}

# Validate that serviceHelper.ps1 exists
$serviceHelperPath = Join-Path -Path $HomeDir -ChildPath "am\bin\tools\serviceHelper.ps1"

if (-not (Test-Path $serviceHelperPath)) {
    Write-Host "Error: Invalid MULE_HOME directory. Could not find $serviceHelperPath"
    Write-Host "Please specify a valid MULE_HOME directory with the -m parameter."
    exit 1
}

# Source the serviceHelper.ps1
. $serviceHelperPath

# Java program running on Windows treats paths differently when the trailing character is \
# If MULE_HOME env is not set, HomeDir is autodetected and things are merry.
# But if HomeDir is supplied as an option, with a valid path but ending in \, then AgentConfiguratorApp complains:
# ERROR: The provided Mule Home doesn't exist, please check if the provided directory is correct.
# Hence the TrimEnd
$HomeDir = $HomeDir.TrimEnd('\','/')
$env:MULE_HOME = $HomeDir

Log-Info "MULE_HOME is set to $HomeDir"


# Set AM_HOME based on the determined HomeDir
$AM_HOME = Join-Path -Path $HomeDir -ChildPath "am"

Log-Info "AM_HOME is set to $AM_HOME"

$amScript = Join-Path -Path $AM_HOME -ChildPath "bin\am.ps1"

# Function to check if running as administrator
function Test-Administrator {
    $currentUser = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
    return $currentUser.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

# Function to unset GOMEMLIMIT environment variable
# Uninstall should clean up this universal GOMEMLIMIT env variable
function Unset-GoMemLimit {
    try {
        Log-Info "Checking for GOMEMLIMIT environment variable set at Machine level..."
        $currentValue = [Environment]::GetEnvironmentVariable("GOMEMLIMIT", "Machine")

        if ($null -ne $currentValue) {
            Log-Info "GOMEMLIMIT is currently set to: $currentValue"
            Log-Info "Removing GOMEMLIMIT environment variable..."
            [Environment]::SetEnvironmentVariable("GOMEMLIMIT", $null, "Machine")

            # Verify removal
            $newValue = [Environment]::GetEnvironmentVariable("GOMEMLIMIT", "Machine")
            if ($null -eq $newValue) {
                Log-Info "GOMEMLIMIT environment variable has been successfully removed."
            } else {
                Log-Info "Warning: Failed to remove GOMEMLIMIT. Current value: $newValue"
            }
        } else {
            Log-Info "GOMEMLIMIT environment variable is not set. No action needed."
        }
    } catch {
        Log-Info "Error removing GOMEMLIMIT environment variable: $($_.Exception.Message)"
    }
}

if (Test-Path $amScript) {

    try {
        # Stop the DirectoryWatcher
        Log-Info "Attempting to stop DirectoryWatcher..."
        $targetClass = "com.mulesoft.dias.mule.agent.DirectoryWatcher"
        # Get all java.exe processes with full command lines
        $javaProcesses = Get-CimInstance Win32_Process | Where-Object {
            $_.Name -eq "java.exe" -and $_.CommandLine -match [regex]::Escape($targetClass)
        }

        $className = $targetClass.Split('.')[-1]

        if ($javaProcesses.Count -eq 0) {
            Log-Info "No running Java process found for class $className."
        }

        foreach ($proc in $javaProcesses) {
            Log-Info "Stopping Java process with PID $($proc.ProcessId) running class $className..."
            Stop-Process -Id $proc.ProcessId -Force
        }

        Log-Info "Stopping Anypoint Monitoring OpenTelemetry Collector."
        Start-Process -FilePath "powershell.exe" -ArgumentList "-File `"$amScript`" stop" -NoNewWindow -Wait
        Log-Info "Anypoint Monitoring OpenTelemetry Collector stopped."
        # Remove directories and files
        Log-Info "Removing configuration files and directories..."
        Remove-Item -Path (Join-Path -Path $AM_HOME -ChildPath "config\prospectors") -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path (Join-Path -Path $AM_HOME -ChildPath "config\certs") -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path (Join-Path -Path $AM_HOME -ChildPath "config\proxy.url") -Force -ErrorAction SilentlyContinue
        Remove-Item -Path (Join-Path -Path $AM_HOME -ChildPath "install.mode") -Force -ErrorAction SilentlyContinue
        Remove-Item -Path (Join-Path -Path $env:AM_HOME -ChildPath "directorywatcher.pid") -Force -ErrorAction SilentlyContinue

        # Remove specific JAR files
        $jarPaths = @(
            "$HomeDir\server-plugins\mule-agent-plugin\lib\mule-agent-dias-*.jar",
            "$HomeDir\server-plugins\mule-agent-plugin\lib\analytics-metrics-collector-*.jar",
            "$HomeDir\server-plugins\mule-agent-plugin\lib\modules\mule-agent-dias-*.jar",
            "$HomeDir\server-plugins\mule-agent-plugin\lib\modules\analytics-metrics-collector-*.jar",
            "$HomeDir\plugins\mule-agent-plugin\lib\modules\mule-agent-dias-*.jar",
            "$HomeDir\plugins\mule-agent-plugin\lib\modules\analytics-metrics-collector-*.jar"
        )

        foreach ($jarPath in $jarPaths) {
            Remove-Item -Path $jarPath -Force -ErrorAction SilentlyContinue
        }

        if (Test-Administrator) {
            Unset-GoMemLimit
        } else {
            $currentValue = [Environment]::GetEnvironmentVariable("GOMEMLIMIT", "Machine")
            Log-Info "Failed to unset GOMEMLIMIT ($currentValue). You must be run as administrator to remove system environment variables."
            Log-Info "Please restart with administrator privileges."
        }

        Log-Info "Anypoint Monitoring uninstallation completed successfully"
        exit 0
    } catch {
        Log-Info "Anypoint Monitoring uninstallation failed."
        exit 1
    }
} else {
    Log-Info "Warning: am.ps1 not found at: $amScript"
    Log-Info "Anypoint Monitoring uninstallation failed"
    exit 1
}