param(
    [Parameter(Position = 0)]
    [string]$Serial,
    [switch]$InstallCompatibleComponents,
    [switch]$InstallSteshApps,
    [switch]$NonInteractive,
    [switch]$CheckOnly
)

$ErrorActionPreference = "Stop"
$kitRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$platformTools = Join-Path $kitRoot "platform-tools"
$adb = Join-Path $platformTools "adb.exe"
if (-not (Test-Path -LiteralPath $adb)) {
    throw "Portable adb.exe is missing from the kit: $adb. Extract the complete ZIP before starting Install.cmd."
}

function Install-Apk {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Path
    )

    $previousErrorActionPreference = $ErrorActionPreference
    try {
        # Windows PowerShell 5.1 can surface native stderr as ErrorRecord objects.
        # Capture all adb output so expected install results can be classified.
        $ErrorActionPreference = "Continue"
        $installLines = & $adb -s $Serial install -r $Path 2>&1 |
            ForEach-Object { $_.ToString() }
        $installOutput = ($installLines -join [Environment]::NewLine).Trim()
        $installExitCode = $LASTEXITCODE
    } finally {
        $ErrorActionPreference = $previousErrorActionPreference
    }

    if ($installOutput) { Write-Host $installOutput }
    if ($installExitCode -eq 0) { return }
    if ($installOutput -match 'INSTALL_FAILED_VERSION_DOWNGRADE') {
        Write-Host "Skipping $([IO.Path]::GetFileName($Path)): a newer version is already installed." -ForegroundColor Yellow
        return
    }

    throw "Failed to install $([IO.Path]::GetFileName($Path)): $installOutput"
}

function Import-AuthorizedAdbKey {
    $desktopKey = Join-Path ([Environment]::GetFolderPath('UserProfile')) ".android\adbkey"
    if (-not (Test-Path -LiteralPath $desktopKey)) {
        throw "The desktop ADB key was not created. Authorize this PC on RT-G2 and run the installer again."
    }

    Write-Host "Configuring Red and Yellow remote buttons..." -ForegroundColor Cyan
    $startInfo = New-Object System.Diagnostics.ProcessStartInfo
    $startInfo.FileName = $adb
    $startInfo.Arguments = "-s $Serial shell content write --uri content://info.technozon.steshmodifier.adbkey/key"
    $startInfo.UseShellExecute = $false
    $startInfo.CreateNoWindow = $true
    $startInfo.RedirectStandardInput = $true
    $startInfo.RedirectStandardOutput = $true
    $startInfo.RedirectStandardError = $true
    $process = New-Object System.Diagnostics.Process
    $process.StartInfo = $startInfo
    if (-not $process.Start()) { throw "Could not start the ADB key importer." }
    try {
        $keyBytes = [IO.File]::ReadAllBytes($desktopKey)
        $process.StandardInput.BaseStream.Write($keyBytes, 0, $keyBytes.Length)
        $process.StandardInput.BaseStream.Flush()
        $process.StandardInput.Close()
        $standardOutput = $process.StandardOutput.ReadToEnd()
        $standardError = $process.StandardError.ReadToEnd()
        $process.WaitForExit()
        if ($process.ExitCode -ne 0) {
            throw "Automatic button setup failed: $standardOutput $standardError"
        }
    } finally {
        $process.Dispose()
    }
}

function Start-AndVerifyButtonService {
    & $adb -s $Serial logcat -c 2>$null
    & $adb -s $Serial shell am force-stop info.technozon.steshmodifier | Out-Null
    & $adb -s $Serial shell am start -n info.technozon.steshmodifier/.MainActivity | Out-Host

    $deadline = (Get-Date).AddSeconds(45)
    $connected = $false
    do {
        Start-Sleep -Seconds 1
        $watcherLog = (& $adb -s $Serial logcat -d -s 'TZ-RTG2-KEYS:I' '*:S' 2>$null | Out-String)
        if ($watcherLog -match 'physical key watcher connected') {
            $connected = $true
            break
        }
    } while ((Get-Date) -lt $deadline)

    if (-not $connected) {
        throw "The remote-button service did not connect to localhost ADB. Keep Network debugging enabled on port 5555 and rerun Install.cmd."
    }
    Write-Host "REMOTE BUTTONS READY: Red = Power menu, Yellow = overlay, Power = system sleep/wake." -ForegroundColor Green
}

Get-ChildItem -LiteralPath $platformTools -File -ErrorAction SilentlyContinue |
    Unblock-File -ErrorAction SilentlyContinue

if ([string]::IsNullOrWhiteSpace($Serial)) {
    if ($NonInteractive) { throw "-Serial is required in non-interactive mode" }
    Write-Host ""
    Write-Host "Enter the RT-G2 IP address shown in network settings." -ForegroundColor Cyan
    Write-Host "Example: 192.168.1.50 or 192.168.1.50:5555"
    $Serial = Read-Host "RT-G2 address"
}
$Serial = $Serial.Trim()
if ($Serial -match '^\d{1,3}(\.\d{1,3}){3}$') { $Serial = "${Serial}:5555" }
if ($Serial -notmatch '^[^\s:]+:\d{1,5}$') {
    throw "Invalid device address: '$Serial'. Expected IP:PORT, for example 192.168.1.50:5555."
}

Write-Host "Using bundled Android Platform Tools:" -ForegroundColor Cyan
& $adb version | Select-Object -First 2 | Out-Host
& $adb start-server | Out-Host
Write-Host "Connecting to $Serial ..." -ForegroundColor Cyan
$connectOutput = (& $adb connect $Serial 2>&1 | Out-String).Trim()
Write-Host $connectOutput

$deadline = (Get-Date).AddSeconds(60)
$state = ""
$authorizationHintShown = $false
do {
    $stateOutput = & $adb -s $Serial get-state 2>$null | Select-Object -Last 1
    $state = ([string]$stateOutput).Trim()
    if ($state -eq "device") { break }
    if (-not $authorizationHintShown) {
        Write-Host "Waiting for the TV box... Confirm the RSA debugging prompt on RT-G2." -ForegroundColor Yellow
        $authorizationHintShown = $true
    }
    Start-Sleep -Seconds 2
} while ((Get-Date) -lt $deadline)
if ($state -ne "device") {
    throw "RT-G2 is not connected/authorized at $Serial. Enable network ADB, keep both devices on the same LAN, accept the RSA prompt, then run Install.cmd again. Last state: '$state'."
}

$apk = Join-Path $kitRoot "TECHNOZON_Modifier_RT-G2_v1.0.21.apk"
if (-not (Test-Path -LiteralPath $apk)) { throw "Modifier APK not found: $apk" }

$profile = [ordered]@{
    model = (& $adb -s $Serial shell getprop ro.product.model).Trim()
    product = (& $adb -s $Serial shell getprop ro.product.name).Trim()
    device = (& $adb -s $Serial shell getprop ro.product.device).Trim()
    sdk = (& $adb -s $Serial shell getprop ro.build.version.sdk).Trim()
    incremental = (& $adb -s $Serial shell getprop ro.build.version.incremental).Trim()
}
if ($profile.model -ne "RT-G2" -or $profile.product -ne "SEI804RT" -or $profile.device -ne "YYJ" -or [int]$profile.sdk -lt 34) {
    throw "Unsupported device profile: $($profile | ConvertTo-Json -Compress)"
}
Write-Host "Compatible device found: $($profile.model) / $($profile.product) / Android SDK $($profile.sdk) / build $($profile.incremental)" -ForegroundColor Green
if ($CheckOnly) {
    Write-Host "CHECK PASSED. Portable ADB and RT-G2 connection work on this PC." -ForegroundColor Green
    return
}

if (-not $NonInteractive) {
    if (-not $PSBoundParameters.ContainsKey('InstallCompatibleComponents')) {
        $answer = Read-Host "Install optional SEI804 tools? [y/N]"
        $InstallCompatibleComponents = $answer -match '^(y|yes)$'
    }
    if (-not $PSBoundParameters.ContainsKey('InstallSteshApps')) {
        $answer = Read-Host "Install STESH TV Search, Subscriptions and TV Boxes? [Y/n]"
        $InstallSteshApps = $answer -notmatch '^(n|no)$'
    }
}

$settings = @(
    "hdmi_control_volume_control_enabled",
    "window_animation_scale",
    "transition_animation_scale",
    "animator_duration_scale"
)
$modifierServices = @(
    "info.technozon.steshmodifier/.InfoOverlayService",
    "info.technozon.steshmodifier/info.technozon.steshmodifier.InfoOverlayService"
)
$originalAccessibility = (& $adb -s $Serial shell settings get secure enabled_accessibility_services).Trim()
if ($originalAccessibility -ne "null") {
    $originalAccessibility = (($originalAccessibility -split ':') |
        Where-Object { $_ -and $_ -notin $modifierServices }) -join ':'
    if ([string]::IsNullOrWhiteSpace($originalAccessibility)) { $originalAccessibility = "null" }
}
$baseline = [ordered]@{
    capturedAt = (Get-Date).ToString("o")
    serial = $Serial
    profile = $profile
    enabledAccessibilityServices = $originalAccessibility
    accessibilityEnabled = (& $adb -s $Serial shell settings get secure accessibility_enabled).Trim()
    homeActivity = (& $adb -s $Serial shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME | Select-Object -Last 1).Trim()
    global = [ordered]@{}
}
foreach ($name in $settings) { $baseline.global[$name] = (& $adb -s $Serial shell settings get global $name).Trim() }
$baselinePath = Join-Path $kitRoot "rtg2-baseline.json"
$baseline | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $baselinePath -Encoding UTF8

Install-Apk -Path $apk
& $adb -s $Serial shell pm grant info.technozon.steshmodifier android.permission.WRITE_SECURE_SETTINGS

& $adb -s $Serial shell settings put secure enabled_accessibility_services $baseline.enabledAccessibilityServices
if ($baseline.enabledAccessibilityServices -eq "null") {
    & $adb -s $Serial shell settings put secure accessibility_enabled 0
} else {
    & $adb -s $Serial shell settings put secure accessibility_enabled 1
}
& $adb -s $Serial shell cmd appops set info.technozon.steshmodifier SYSTEM_ALERT_WINDOW allow
Import-AuthorizedAdbKey

if ($InstallCompatibleComponents) {
    Get-ChildItem -LiteralPath (Join-Path $kitRoot "components") -Filter *.apk | ForEach-Object {
        Install-Apk -Path $_.FullName
    }
}
if ($InstallSteshApps) {
    Get-ChildItem -LiteralPath (Join-Path $kitRoot "stesh") -Filter *.apk | ForEach-Object {
        Install-Apk -Path $_.FullName
    }
}

Start-AndVerifyButtonService
Write-Host "TECHNOZON Modifier RT-G2 installed successfully." -ForegroundColor Green
Write-Host "Rollback baseline: $baselinePath"
