$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

function Resolve-BinPath {
    if ($env:BIN -and (Test-Path $env:BIN)) {
        return (Resolve-Path $env:BIN).Path
    }

    $selfDir = Split-Path -Parent $PSCommandPath
    $releaseBin = Join-Path $selfDir "agw-standalone-api.exe"
    if (Test-Path $releaseBin) {
        return $releaseBin
    }

    $workspaceBin = Join-Path $selfDir "..\\target\\release\\agw-standalone-api.exe"
    if (Test-Path $workspaceBin) {
        return (Resolve-Path $workspaceBin).Path
    }

    throw "未找到 agw-standalone-api.exe，可设置 BIN=C:\\path\\agw-standalone-api.exe 后重试。"
}

function Wait-HttpJson {
    param(
        [Parameter(Mandatory = $true)][string]$Uri,
        [Parameter(Mandatory = $true)][int]$Attempts,
        [Parameter(Mandatory = $true)][int]$SleepSeconds,
        [Parameter(Mandatory = $true)][scriptblock]$Condition,
        [Parameter(Mandatory = $true)][string]$TimeoutMessage
    )

    for ($i = 0; $i -lt $Attempts; $i++) {
        try {
            $response = Invoke-RestMethod -Uri $Uri -Method Get
            if (& $Condition $response) {
                return $response
            }
        } catch {
        }
        Start-Sleep -Seconds $SleepSeconds
    }

    throw $TimeoutMessage
}

$binPath = Resolve-BinPath
$keyJson = & $binPath keygen eth 2>$null | ConvertFrom-Json
if (-not $keyJson.private_key_hex) {
    throw "keygen 失败"
}

$env:AGW_ETH_PRIVKEY = $keyJson.private_key_hex
if (-not $env:AGW_MEMORY_OWNER_KEY) {
    $env:AGW_MEMORY_OWNER_KEY = "bootstrap-local"
}
$env:AGW_CHAIN_BACKEND = "smoldot"
Remove-Item Env:AGW_AGENT_ID -ErrorAction SilentlyContinue

if (-not $env:AGW_BIND) {
    $env:AGW_BIND = "127.0.0.1:8790"
}

$bindHost = "127.0.0.1"
$port = "8790"
if ($env:AGW_BIND -match '^(.*):(\d+)$') {
    $bindHost = $Matches[1]
    $port = $Matches[2]
}
$curlHost = if ($bindHost -in @("0.0.0.0", "::", "[::]")) { "127.0.0.1" } else { $bindHost }
$base = "http://$curlHost:$port"
$headers = @{ "x-agw-local-agent" = "1" }

Write-Host "启动 Gateway（smoldot 同步可能需数分钟）… BIN=$binPath"
$process = Start-Process -FilePath $binPath -PassThru
try {
    Wait-HttpJson -Uri "$base/health" -Attempts 120 -SleepSeconds 1 -TimeoutMessage "等待 /health 超时" -Condition {
        param($body) $body.status -eq "ok"
    } | Out-Null

    Wait-HttpJson -Uri "$base/v1/epoch" -Attempts 360 -SleepSeconds 2 -TimeoutMessage "等待 epoch 超时" -Condition {
        param($body) $null -ne $body.epoch
    } | Out-Null

    Write-Host "领水 address=$($keyJson.address_hex) …"
    $claimBody = @{ address = $keyJson.address_hex } | ConvertTo-Json -Compress
    $claim = Invoke-RestMethod -Uri "$base/v1/faucet/claim" -Method Post -Headers $headers -ContentType "application/json" -Body $claimBody
    $claim | ConvertTo-Json -Depth 8

    Write-Host "注册 agent（本地显示名 donald）…"
    $register = Invoke-RestMethod -Uri "$base/v1/register" -Method Post -Headers $headers -ContentType "application/json" -Body '{"agent_name":"donald"}'
    $register | ConvertTo-Json -Depth 8
    if (-not $register.agent_id) {
        throw "注册失败或未返回 agent_id"
    }

    $agentId = [string]$register.agent_id

    Write-Host "校验 submit_heartbeat（不消耗 gas）…"
    $validateHeartbeat = @{
        agent_id = $agentId
        action = "submit_heartbeat"
        payload = @{}
    } | ConvertTo-Json -Compress
    Invoke-RestMethod -Uri "$base/v1/actions/validate" -Method Post -Headers $headers -ContentType "application/json" -Body $validateHeartbeat | ConvertTo-Json -Depth 8

    Write-Host "提交 submit_heartbeat（单笔交易，gas 由链上决定）…"
    $submitHeartbeat = @{
        agent_id = $agentId
        action = "submit_heartbeat"
        payload = @{}
    } | ConvertTo-Json -Compress
    Invoke-RestMethod -Uri "$base/v1/agents/$agentId/submit" -Method Post -Headers $headers -ContentType "application/json" -Body $submitHeartbeat | ConvertTo-Json -Depth 8

    Write-Host "再校验 move north（仅 validate，不 submit，省 gas）…"
    $validateMove = @{
        agent_id = $agentId
        action = "move"
        payload = @{ direction = "north" }
    } | ConvertTo-Json -Compress
    Invoke-RestMethod -Uri "$base/v1/actions/validate" -Method Post -Headers $headers -ContentType "application/json" -Body $validateMove | ConvertTo-Json -Depth 8

    Write-Host "完成。agent_id=$agentId"
} finally {
    if ($process -and -not $process.HasExited) {
        Stop-Process -Id $process.Id -Force
    }
}
