param(
    [Parameter(Mandatory = $true)][string]$DataRoot,
    [Parameter(Mandatory = $true)][string]$OutputRoot,
    [Parameter(Mandatory = $true)][string]$RtkCapture,
    [Parameter(Mandatory = $true)][string]$ImuCapture,
    [string]$LidarObject = "frontlidar",
    [string]$Timezone = "+08:00",
    [string[]]$StationNames = @(),
    [int]$Stride = 1,
    [double]$RtkMaxDtMs = 150.0,
    [double]$ImuBeforeMs = 100.0,
    [double]$ImuAfterMs = 100.0,
    [switch]$SkipLidarExport,
    [switch]$SkipSerialParsing
)

$ErrorActionPreference = "Stop"
$RepoRoot = Split-Path -Parent $PSScriptRoot
$Exporter = Join-Path $RepoRoot "tools\frontlidar_dlog_export.py"
$Builder = Join-Path $RepoRoot "tools\build_multisensor_npz.py"
$Parser = Join-Path $RepoRoot "tools\rscap_v2\parse_rtk_imu_v2.py"
$Auditor = Join-Path $RepoRoot "tools\rscap_v2\audit_capture_v2.py"
$ExportRoot = Join-Path $OutputRoot "export"
$ParsedRoot = Join-Path $OutputRoot "parsed"
$CombinedRoot = Join-Path $OutputRoot "combined"

function Run-Python {
    param([string]$Stage, [string[]]$Arguments)
    Write-Host "[$Stage]"
    & python @Arguments
    if ($LASTEXITCODE -ne 0) {
        throw "$Stage failed with Python exit code $LASTEXITCODE"
    }
}

foreach ($Path in @($DataRoot, $RtkCapture, $ImuCapture)) {
    if (-not (Test-Path -LiteralPath $Path)) { throw "Input does not exist: $Path" }
}
if ($Stride -lt 1) { throw "Stride must be at least 1" }

if ($StationNames.Count -gt 0) {
    $Stations = @($StationNames | ForEach-Object { Get-Item -LiteralPath (Join-Path $DataRoot $_) })
} else {
    $Stations = @(Get-ChildItem -LiteralPath $DataRoot -Directory | Where-Object {
        (Test-Path -LiteralPath (Join-Path $_.FullName "dobject")) -and
        (Test-Path -LiteralPath (Join-Path $_.FullName "dobject_recording"))
    } | Sort-Object Name)
}
if ($Stations.Count -eq 0) { throw "No station directory containing dobject and dobject_recording was found" }

New-Item -ItemType Directory -Force -Path $OutputRoot | Out-Null
if (-not $SkipSerialParsing) {
    New-Item -ItemType Directory -Force -Path $ParsedRoot | Out-Null
    Run-Python "capture audit" @($Auditor, $RtkCapture, $ImuCapture, "--out", (Join-Path $OutputRoot "capture_audit.json"))
    Run-Python "RTK/IMU parse" @($Parser, "--rtk", $RtkCapture, "--imu", $ImuCapture, "--out", $ParsedRoot)
}

foreach ($Station in $Stations) {
    $StationOut = Join-Path $ExportRoot $Station.Name
    if (-not $SkipLidarExport) {
        Run-Python "LiDAR station $($Station.Name)" @(
            $Exporter, "--dlog", $Station.FullName, "--out", $StationOut,
            "--object", $LidarObject, "--format", "npz", "--timezone", $Timezone,
            "--stride", "$Stride", "--compress", "--skip-rtk", "--write-reports", "--resume"
        )
    }
    if (-not (Test-Path -LiteralPath (Join-Path $StationOut "frames"))) {
        throw "Exported frame directory is absent for station $($Station.Name): $StationOut"
    }
}

$BuildArgs = @($Builder)
foreach ($Station in $Stations) {
    $Frames = Join-Path (Join-Path $ExportRoot $Station.Name) "frames"
    $BuildArgs += @("--lidar", "$($Station.Name)=$Frames")
}
$BuildArgs += @(
    "--rtk", (Join-Path $ParsedRoot "rtk.jsonl"),
    "--imu", (Join-Path $ParsedRoot "imu.jsonl"),
    "--out", $CombinedRoot,
    "--rtk-max-dt-ms", "$RtkMaxDtMs",
    "--imu-before-ms", "$ImuBeforeMs",
    "--imu-after-ms", "$ImuAfterMs",
    "--overwrite"
)
Run-Python "LiDAR/RTK/IMU association" $BuildArgs

Write-Host "Completed stations: $($Stations.Count)"
Write-Host "Combined NPZ: $CombinedRoot"
