[CmdletBinding()]
param(
    [Parameter(Position = 0)]
    [string]$ModelPath
)

$ErrorActionPreference = 'Stop'
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = Split-Path -Parent $scriptDirectory
$defaultsFilePath = Join-Path $scriptDirectory 'test-automation.defaults.json'

function Resolve-RoamerPath {
    $candidates = New-Object System.Collections.Generic.List[string]
    $appPathKeys = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\App Paths\Roamer.exe'
    )

    foreach ($key in $appPathKeys) {
        try {
            $value = (Get-ItemProperty -Path $key -ErrorAction Stop).'(default)'
            if (-not [string]::IsNullOrWhiteSpace($value)) {
                $candidates.Add($value)
            }
        }
        catch {
        }
    }

    $wellKnownPaths = @(
        (Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Manage 2026\Roamer.exe'),
        (Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Manage 2026\Roamer.exe'),
        (Join-Path ${env:ProgramFiles} 'Autodesk\Navisworks Simulate 2026\Roamer.exe'),
        (Join-Path ${env:ProgramFiles(x86)} 'Autodesk\Navisworks Simulate 2026\Roamer.exe')
    ) | Where-Object { $_ }

    foreach ($path in $wellKnownPaths) {
        $candidates.Add($path)
    }

    foreach ($candidate in $candidates | Select-Object -Unique) {
        if (-not [string]::IsNullOrWhiteSpace($candidate) -and (Test-Path $candidate)) {
            return [System.IO.Path]::GetFullPath($candidate)
        }
    }

    throw '找不到 Roamer.exe。请确认 Navisworks Manage 2026 已安装。'
}

function Resolve-DefaultModelPath {
    if (-not (Test-Path $defaultsFilePath)) {
        return $null
    }

    try {
        $defaults = Get-Content $defaultsFilePath -Raw | ConvertFrom-Json
        $defaultModelPath = [string]$defaults.defaultModelPath
        if ([string]::IsNullOrWhiteSpace($defaultModelPath)) {
            return $null
        }

        $resolvedPath = [System.IO.Path]::GetFullPath($defaultModelPath)
        if (-not (Test-Path $resolvedPath)) {
            throw "默认模型文件不存在: $resolvedPath"
        }

        return $resolvedPath
    }
    catch {
        throw "读取默认测试配置失败: $($_.Exception.Message)"
    }
}

function Dismiss-RecoveryPromptIfPresent {
    param(
        [int]$TimeoutSeconds = 20
    )

    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $shell = New-Object -ComObject WScript.Shell
    # NW 启动恢复提示框标题关键词（覆盖“从自动保存重新载入”“是否打开之前保存的模型”等变体）
    $windowTitleKeywords = @(
        '自动保存',
        '保存的模型',
        '重新载入',
        '恢复'
    )

    $deadline = (Get-Date).AddSeconds($TimeoutSeconds)
    while ((Get-Date) -lt $deadline) {
        foreach ($keyword in $windowTitleKeywords) {
            try {
                # AppActivate 支持子串匹配，激活标题包含关键词的窗口
                if ($shell.AppActivate($keyword)) {
                    Start-Sleep -Milliseconds 300
                    [System.Windows.Forms.SendKeys]::SendWait('%N')
                    Write-Host "已自动选择“否”以跳过恢复提示框（关键词: $keyword）。"
                    return
                }
            }
            catch {
            }
        }

        Start-Sleep -Milliseconds 300
    }
}

function Clear-NavisworksAutoSave {
    # 清理 NW 自动保存文件：NW 启动时检测到 AutoSave 残留会弹“是否打开之前保存的模型”
    # 提示框并拦截命令行打开请求。测试环境提前清理可彻底避免弹窗（测试前先正常退出 NW 以保存用户数据）。
    $autoSaveDir = Join-Path $env:APPDATA 'Autodesk\Navisworks Manage 2026\AutoSave'
    if (Test-Path $autoSaveDir) {
        $removedCount = (Get-ChildItem $autoSaveDir -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue | Measure-Object).Count
        Write-Host "已清理 Navisworks 自动保存文件（避免恢复提示框）: $autoSaveDir"
    }
}

if ([string]::IsNullOrWhiteSpace($ModelPath)) {
    $ModelPath = Resolve-DefaultModelPath
}

if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
    $ModelPath = [System.IO.Path]::GetFullPath($ModelPath)
    if (-not (Test-Path $ModelPath)) {
        throw "模型文件不存在: $ModelPath"
    }
}

$roamerPath = Resolve-RoamerPath
$existingProcess = Get-Process Roamer -ErrorAction SilentlyContinue | Select-Object -First 1
$env:TRANSPORTPLUGIN_TEST_AUTOMATION = '1'

if ($existingProcess) {
    Write-Host ("Navisworks 已在运行，PID={0}" -f $existingProcess.Id)
    if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
        # 通过文件关联请求打开模型（Start-Process 传参对 NW 2026 不可靠）
        Start-Process -FilePath $ModelPath | Out-Null
        Write-Host ("已请求 Navisworks 打开模型: {0}" -f $ModelPath)
    }

    Dismiss-RecoveryPromptIfPresent -TimeoutSeconds 30

    Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动，首次测试前请确保插件面板已打开。'
    exit 0
}

# 启动前清理自动保存文件，避免 NW 弹出恢复提示框（弹窗会拦截命令行打开模型）
Clear-NavisworksAutoSave

if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
    # 直接通过文件关联启动并打开模型（NW 2026 命令行传参打开文件不可靠）
    $startProcess = Start-Process -FilePath $ModelPath -PassThru
    $processId = $startProcess.Id
    Write-Host ("Navisworks 启动中（文件关联），PID={0}" -f $processId)
}
else {
    $process = Start-Process -FilePath $roamerPath -PassThru
    $processId = $process.Id
    Write-Host ("Navisworks 启动中，PID={0}" -f $processId)
}

$deadline = (Get-Date).AddSeconds(30)
do {
    Start-Sleep -Milliseconds 500
    $running = Get-Process -Id $processId -ErrorAction SilentlyContinue
} while (-not $running -and (Get-Date) -lt $deadline)

if (-not $running) {
    throw 'Navisworks 启动超时，30 秒内未检测到 Roamer.exe 进程。'
}

# 兜底：清理 AutoSave 后通常无恢复弹窗；短超时单次处理可能出现的其他提示框
Dismiss-RecoveryPromptIfPresent -TimeoutSeconds 3

Write-Host ("Navisworks 已启动: {0}" -f $roamerPath)
if (-not [string]::IsNullOrWhiteSpace($ModelPath)) {
    Write-Host ("已打开模型参数: {0}" -f $ModelPath)
}

Write-Host '提示: 当前测试 HTTP 服务在插件 DockPane OnLoaded 中启动，首次测试前请确保插件面板已打开。'
