# MK11 Accessibility installer.
#
# Copies the mod into a Mortal Kombat 11 folder and writes Reloaded-II\Apps\MK11\AppConfig.json
# with THIS machine's paths. That file is the reason there is an installer at all: it stores an
# absolute path to MK11.exe, so it cannot be shipped pre-made in the zip.
#
# Everything else in the tree is path independent. The loader DLL works out where the game is at
# runtime from its own module path, so no registry entry, no admin rights and no launcher.

param(
    [string] $GamePath,
    [switch] $Uninstall
)

$ErrorActionPreference = 'Stop'
$here = Split-Path -Parent $MyInvocation.MyCommand.Path

function Say([string] $m) { Write-Host $m }

function Test-GameFolder([string] $p) {
    if ([string]::IsNullOrWhiteSpace($p)) { return $false }
    return (Test-Path (Join-Path $p 'Binaries\Retail\MK11.exe'))
}

# Look in the usual Steam places, then in every extra Steam library the user has set up.
function Find-Game {
    $tries = New-Object System.Collections.Generic.List[string]
    foreach ($root in @(${env:ProgramFiles(x86)}, $env:ProgramFiles, 'C:')) {
        if ($root) { $tries.Add((Join-Path $root 'Steam\steamapps\common\Mortal Kombat 11')) }
    }
    foreach ($vdf in @("${env:ProgramFiles(x86)}\Steam\steamapps\libraryfolders.vdf",
                       "$env:ProgramFiles\Steam\steamapps\libraryfolders.vdf")) {
        if (-not (Test-Path $vdf)) { continue }
        foreach ($line in (Get-Content $vdf)) {
            if ($line -match '"path"\s+"(.+?)"') {
                $lib = $matches[1] -replace '\\\\', '\'
                $tries.Add((Join-Path $lib 'steamapps\common\Mortal Kombat 11'))
            }
        }
    }
    foreach ($t in $tries) { if (Test-GameFolder $t) { return $t } }
    return $null
}

Say ''
Say 'Mortal Kombat 11 accessibility mod'
Say ''

# 1. Work out which folder to install into.
#    If a folder was named explicitly and it is wrong, STOP. Quietly searching elsewhere
#    would mean acting on a folder the user did not ask for, which for the uninstall path
#    means deleting from the wrong copy of the game.
if ($GamePath -and -not (Test-GameFolder $GamePath)) {
    Say "That folder does not contain Binaries\Retail\MK11.exe:"
    Say "  $GamePath"
    Say ''
    Say 'Nothing was changed. Run this again without naming a folder to search automatically.'
    Say ''
    exit 1
}
if (-not $GamePath) {
    $GamePath = Find-Game
    if ($GamePath) { Say "Found the game at: $GamePath" }
}

while (-not (Test-GameFolder $GamePath)) {
    Say 'I could not find Mortal Kombat 11 automatically.'
    Say 'Type or paste the full path to your Mortal Kombat 11 folder, then press Enter.'
    Say 'It is the folder that contains a folder called Binaries. Leave it empty to cancel.'
    $GamePath = (Read-Host 'Game folder').Trim('"', ' ')
    if ([string]::IsNullOrWhiteSpace($GamePath)) { Say 'Cancelled. Nothing was changed.'; exit 1 }
    if (-not (Test-GameFolder $GamePath)) { Say ''; Say 'That folder does not contain Binaries\Retail\MK11.exe.'; Say '' }
}

$proxy = Join-Path $GamePath 'Binaries\Retail\dinput8.dll'

# 2. Uninstall is genuinely just deleting the one file that gets loaded.
if ($Uninstall) {
    if (Test-Path $proxy) {
        Remove-Item $proxy -Force
        Say ''
        Say 'Removed. The mod will not load next time you start the game.'
        Say 'The Reloaded-II folder was left in place and is harmless. Delete it if you want.'
    } else {
        Say ''
        Say 'The mod was not installed in that folder. Nothing was changed.'
    }
    Say ''
    exit 0
}

# 3. Refuse to write into a running game: MK11 holds the mod DLL open and the copy would
#    fail silently, leaving a half installed mod that looks installed.
if (Get-Process -Name 'MK11*' -ErrorAction SilentlyContinue) {
    Say ''
    Say 'Mortal Kombat 11 is running. Close the game completely, then run this again.'
    Say ''
    exit 1
}

# 4. Copy the payload.
Say ''
Say 'Installing.'
Copy-Item (Join-Path $here 'files\Binaries')   $GamePath -Recurse -Force
Copy-Item (Join-Path $here 'files\Reloaded-II') $GamePath -Recurse -Force

# 5. Write the one file that has to know where this machine keeps the game.
$retail  = Join-Path $GamePath 'Binaries\Retail'
$appsDir = Join-Path $GamePath 'Reloaded-II\Apps\MK11'
New-Item -ItemType Directory -Force $appsDir | Out-Null

$appConfig = [ordered]@{
    AppId                    = 'MK11.exe'
    AppName                  = 'Mortal Kombat 11'
    AppLocation              = (Join-Path $retail 'MK11.exe')
    AppArguments             = ''
    AppIcon                  = ''
    AutoInject               = $false
    EnabledMods              = @('MK11.Accessibility')
    WorkingDirectory         = $retail
    PluginData               = @{}
    SortedMods               = @()
    PreserveDisabledModOrder = $true
    DontInject               = $false
    IsMsStore                = $false
}
$appConfig | ConvertTo-Json -Depth 5 | Set-Content (Join-Path $appsDir 'AppConfig.json') -Encoding utf8

# 5a. Clear a leftover debug file from an older build.
#
# Copy-Item -Force overwrites but never DELETES, so anything that stops shipping lingers in
# the mod folder forever. Only one file ever has: the debug symbols beside the mod DLL.
# It is harmless but it is dead weight, and it is the kind of thing people notice and ask
# about. Injustice 2's updater does the same.
$stalePdb = Join-Path $GamePath 'Reloaded-II\Mods\MK11.Accessibility\MK11.Accessibility.pdb'
if (Test-Path $stalePdb) {
    try { Remove-Item $stalePdb -Force; Say '  removed a leftover debug file from an older build' } catch { }
}

# 5b. Record the installed version, and put the updater somewhere findable.
#
# The stamp is what update.ps1 compares against; without it every check would report
# "unknown" and offer an update you already have. $ModVersion is read from the mod's own
# ModConfig.json rather than hardcoded here, so it cannot disagree with what shipped.
#
# The updater itself goes to Documents\MK11 Accessibility -- the same folder the F7 bug
# reports land in. That is deliberate: one short, sayable path holds both things a user
# ever needs to find, instead of asking them back into Program Files.
$modCfg = Join-Path $GamePath 'Reloaded-II\Mods\MK11.Accessibility\ModConfig.json'
$ModVersion = ''
if (Test-Path $modCfg) {
    try { $ModVersion = ((Get-Content $modCfg -Raw) | ConvertFrom-Json).ModVersion } catch { }
}
if ([string]::IsNullOrWhiteSpace($ModVersion)) { $ModVersion = 'unknown' }
Set-Content -Path (Join-Path $GamePath 'accesskit_version.txt') -Value $ModVersion -Encoding utf8

$docs = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'MK11 Accessibility'
try {
    New-Item -ItemType Directory -Force $docs | Out-Null
    foreach ($f in @('update.ps1', 'Check for Updates.bat')) {
        $src = Join-Path $here $f
        if (Test-Path $src) { Copy-Item $src $docs -Force }
    }
} catch {
    Say "  (could not place the updater in Documents: $($_.Exception.Message))"
}

# 6. Confirm what actually landed, rather than assuming the copy worked.
$ok = (Test-Path $proxy) -and
      (Test-Path (Join-Path $GamePath 'Reloaded-II\Mods\MK11.Accessibility\MK11.Accessibility.dll')) -and
      (Test-Path (Join-Path $appsDir 'AppConfig.json'))

Say ''
if ($ok) {
    Say 'Done. The mod is installed.'
    Say ''
    Say "Installed to: $GamePath"
    Say 'Start the game using MK11.exe, not MK11_DX12.exe.'
    Say 'You should hear: Mortal Kombat 11 accessibility loaded.'
    Say ''
    Say 'In your Documents folder there is now a folder called MK11 Accessibility.'
    Say 'It holds "Check for Updates", and it is where F7 saves bug reports.'
} else {
    Say 'Something did not copy correctly. The mod is probably not installed.'
    Say 'Check that you have permission to write to the game folder, then try again.'
    exit 1
}
Say ''
