#Requires -RunAsAdministrator
# Background watcher: copy Sota temp sing-box config into CPC capture folder.
$ErrorActionPreference = "Continue"
$Host.UI.RawUI.WindowTitle = "CPC Sota Capture Watcher"
. (Join-Path $PSScriptRoot "_env.ps1")

$destDir = Join-Path $MergedDir "sota-captured"
New-Item -ItemType Directory -Force -Path $destDir | Out-Null
$statusPath = Join-Path $destDir "watcher-status.json"
$logPath = Join-Path $destDir "watcher.log"
$temps = @("C:\Windows\TEMP", "C:\Windows\Temp", $env:TEMP)

function Write-WatchLog([string]$msg) {
  $line = "$(Get-Date -Format o) $msg"
  Add-Content -Path $logPath -Value $line -Encoding UTF8
}

function Save-WatcherStatus([hashtable]$Data) {
  $Data["time"] = (Get-Date).ToString("o")
  $Data["pid"] = $PID
  ($Data | ConvertTo-Json -Depth 5) | Set-Content -Path $statusPath -Encoding UTF8
}

function Get-FileSha([string]$Path) {
  try { return (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash } catch { return $null }
}

function Capture-One([System.IO.FileInfo]$File) {
  Start-Sleep -Milliseconds 200
  if (-not (Test-Path -LiteralPath $File.FullName)) { return $false }

  $stamp = Get-Date -Format "yyyyMMdd-HHmmss"
  $dest = Join-Path $destDir ("sota-singbox-" + $stamp + ".json")
  try {
    Copy-Item -LiteralPath $File.FullName -Destination $dest -Force
    Copy-Item -LiteralPath $dest -Destination (Join-Path $destDir "latest.json") -Force
  } catch {
    Write-WatchLog ("copy failed: " + $_.Exception.Message)
    return $false
  }

  $server = "?"
  $port = 0
  $vlessN = 0
  try {
    $j = Get-Content $dest -Raw -Encoding UTF8 | ConvertFrom-Json
    $vless = @($j.outbounds | Where-Object { $_.type -eq "vless" })
    $vlessN = $vless.Count
    if ($vlessN -gt 0) {
      $server = [string]$vless[0].server
      $port = [int]$vless[0].server_port
    }
    ("proxy:{0}:{1}" -f $server, $port) | Set-Content (Join-Path $destDir "last-servers.txt") -Encoding UTF8
  } catch {
    Write-WatchLog ("parse warn: " + $_.Exception.Message)
  }

  Save-WatcherStatus @{
    state = "captured"
    lastCapture = (Get-Date).ToString("o")
    dest = $dest
    server = $server
    port = $port
    vlessCount = $vlessN
    source = $File.FullName
  }
  Write-WatchLog ("CAPTURED server=" + $server + ":" + $port + " -> " + $dest)

  try {
    $py = Find-CpcPython
    $reg = $null
    if ($DesktopApp) { $reg = Join-Path $DesktopApp "register_capture.py" }
    if ($py -and $reg -and (Test-Path $reg)) {
      $env:CLAUDE_PROXY_HOME = $ProductHome
      $out = & $py $reg $dest 2>&1 | Out-String
      Write-WatchLog ("DB: " + $out.Trim())
    } else {
      Write-WatchLog "DB: python/register_capture.py missing - skipped"
    }
  } catch {
    Write-WatchLog ("DB register warn: " + $_.Exception.Message)
  }
  return $true
}

Write-WatchLog "CPC Watcher started"
Save-WatcherStatus @{ state = "running"; lastCapture = $null }
Write-Host "CPC Sota Capture Watcher running. Capture dir: $destDir"

$seen = @{}
while ($true) {
  try {
    foreach ($t in $temps) {
      if (-not (Test-Path $t)) { continue }
      $hits = @(Get-ChildItem -LiteralPath $t -Filter "sota-singbox-*.json" -Force -ErrorAction SilentlyContinue)
      foreach ($f in $hits) {
        $sha = Get-FileSha $f.FullName
        if (-not $sha) { continue }
        $key = $f.FullName
        if ($seen.ContainsKey($key) -and $seen[$key] -eq $sha) { continue }
        if (Capture-One $f) { $seen[$key] = $sha }
      }
    }
    $alive = @{}
    foreach ($k in @($seen.Keys)) {
      if (Test-Path -LiteralPath $k) { $alive[$k] = $seen[$k] }
    }
    $seen = $alive
  } catch {
    Write-WatchLog ("loop error: " + $_.Exception.Message)
  }
  Start-Sleep -Seconds 2
}
