param(
    [Parameter(Mandatory = $true)]
    [string]$VersionName,

    [Parameter(Mandatory = $true)]
    [int]$VersionCode
)

$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
$env:JAVA_HOME = "C:\Program Files\Android\Android Studio1\jbr"
$env:PATH = "$env:JAVA_HOME\bin;$env:PATH"

$Server = "root@5.188.21.226"
$BaseUrl = "https://updates.bearmsk.ru"
$RemoteDir = "/var/www/html/updates"
$SshKey = Join-Path $env:USERPROFILE ".ssh\durakometr_release"

if ($VersionName -notmatch '^[0-9A-Za-z._-]+$') {
    throw "Unsafe versionName: $VersionName"
}

if ($VersionCode -le 0) {
    throw "Invalid versionCode: $VersionCode"
}

$ProjectRoot = $PSScriptRoot
$Apk = Join-Path $ProjectRoot "app\build\outputs\apk\release\app-release.apk"
$NotesFile = Join-Path $ProjectRoot "release-notes.txt"

if (-not (Test-Path $Apk)) {
    throw "APK not found: $Apk"
}

$ApkInfo = Get-Item $Apk

if ($ApkInfo.Length -lt 1MB) {
    throw "APK is suspiciously small: $($ApkInfo.Length) bytes"
}

if (-not (Test-Path $SshKey)) {
    throw "SSH key not found: $SshKey"
}

$BuildToolsRoot = Join-Path $env:LOCALAPPDATA "Android\Sdk\build-tools"

if (-not (Test-Path $BuildToolsRoot)) {
    throw "Android build-tools not found: $BuildToolsRoot"
}

$ApkSigner = Get-ChildItem $BuildToolsRoot -Directory |
    Sort-Object Name -Descending |
    ForEach-Object {
        $Candidate = Join-Path $_.FullName "apksigner.bat"
        if (Test-Path $Candidate) {
            $Candidate
        }
    } |
    Select-Object -First 1

if (-not $ApkSigner) {
    throw "apksigner.bat not found"
}

& $ApkSigner verify --verbose $Apk

if ($LASTEXITCODE -ne 0) {
    throw "APK signature verification failed"
}

$Sha256 = (Get-FileHash -Algorithm SHA256 $Apk).Hash.ToLowerInvariant()

$Notes = "Application update"

if (Test-Path $NotesFile) {
    $LoadedNotes = (Get-Content $NotesFile -Raw -Encoding UTF8).Trim()

    if (-not [string]::IsNullOrWhiteSpace($LoadedNotes)) {
        $Notes = $LoadedNotes
    }
}

$RemoteName = "durakometr-$VersionName.apk"
$RemoteTemp = "$RemoteDir/.$RemoteName.uploading"
$RemoteFinal = "$RemoteDir/$RemoteName"

$LocalJson = Join-Path $env:TEMP "durakometr-latest-$VersionCode.json"
$RemoteJsonTemp = "$RemoteDir/.latest.json.uploading"
$RemoteJsonFinal = "$RemoteDir/latest.json"

$Metadata = [ordered]@{
    versionCode = $VersionCode
    versionName = $VersionName
    apkUrl = "$BaseUrl/$RemoteName"
    sha256 = $Sha256
    mandatory = $false
    notes = $Notes
}

$Json = $Metadata | ConvertTo-Json -Depth 5

[System.IO.File]::WriteAllText(
    $LocalJson,
    $Json,
    [System.Text.UTF8Encoding]::new($false)
)

$SshArgs = @(
    "-i", $SshKey,
    "-o", "BatchMode=yes",
    "-o", "ConnectTimeout=10"
)

Write-Host ""
Write-Host "=== Durakometr release $VersionName ($VersionCode) ==="
Write-Host "APK: $([math]::Round($ApkInfo.Length / 1MB, 2)) MB"
Write-Host "SHA256: $Sha256"
Write-Host ""

& scp.exe @SshArgs $Apk "${Server}:$RemoteTemp"

if ($LASTEXITCODE -ne 0) {
    throw "APK upload failed"
}

$RemoteSizeLines = & ssh.exe @SshArgs $Server "stat -c%s '$RemoteTemp'"

if ($LASTEXITCODE -ne 0) {
    throw "Failed to read remote APK size"
}

$RemoteSizeText = ($RemoteSizeLines | Select-Object -Last 1).ToString().Trim()

[long]$RemoteSize = 0

if (-not [long]::TryParse($RemoteSizeText, [ref]$RemoteSize)) {
    throw "Invalid remote APK size: $RemoteSizeText"
}

if ($RemoteSize -ne $ApkInfo.Length) {
    & ssh.exe @SshArgs $Server "rm -f '$RemoteTemp'"
    throw "Size mismatch. Local=$($ApkInfo.Length), remote=$RemoteSize"
}

& scp.exe @SshArgs $LocalJson "${Server}:$RemoteJsonTemp"

if ($LASTEXITCODE -ne 0) {
    & ssh.exe @SshArgs $Server "rm -f '$RemoteTemp'"
    throw "latest.json upload failed"
}

$PublishCommand = "set -e; " +
    "test -s '$RemoteTemp'; " +
    "test -s '$RemoteJsonTemp'; " +
    "mv -f '$RemoteTemp' '$RemoteFinal'; " +
    "chmod 644 '$RemoteFinal'; " +
    "mv -f '$RemoteJsonTemp' '$RemoteJsonFinal'; " +
    "chmod 644 '$RemoteJsonFinal'; " +
    "stat -c '%n %s bytes' '$RemoteFinal'; " +
    "cat '$RemoteJsonFinal'"

& ssh.exe @SshArgs $Server $PublishCommand

if ($LASTEXITCODE -ne 0) {
    throw "Server publish step failed"
}

Remove-Item $LocalJson -Force -ErrorAction SilentlyContinue

Write-Host ""
Write-Host "=============================================="
Write-Host "RELEASE PUBLISHED"
Write-Host "Version: $VersionName ($VersionCode)"
Write-Host "APK: $([math]::Round($ApkInfo.Length / 1MB, 2)) MB"
Write-Host "SHA256: $Sha256"
Write-Host "$BaseUrl/$RemoteName"
Write-Host "=============================================="
