<#
.SYNOPSIS
    SHT30 온습도 STM32F407 펌웨어 빌드 (sht30_fw) — Ninja + arm-none-eabi.

.DESCRIPTION
    firmware/ 를 소스 루트로, firmware/build 를 빌드 디렉터리로 CMake(Ninja)
    구성/빌드한다. 크로스 툴체인 파일(cmake/arm-none-eabi-toolchain.cmake)을
    사용하며, sht30_fw 실행 타깃을 산출한다.

    폐쇄망(air-gapped): 이 스크립트는 네트워크에 접속하지 않는다. 모든 의존성은
    firmware/third_party 에 사전 벤더링되어 있어야 한다(scripts/vendor.ps1 참조).
    third_party 가 없으면 CMake configure 단계에서 즉시 실패한다.

.PARAMETER BuildType
    CMAKE_BUILD_TYPE (Release | RelWithDebInfo | Debug). 기본 Release.

.PARAMETER Clean
    빌드 디렉터리를 먼저 삭제하고 새로 구성한다(클린 빌드).

.PARAMETER ToolchainPrefix
    arm-none-eabi 접두 경로 override (PATH 에 없을 때).
    예) "C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/arm-none-eabi-"

.EXAMPLE
    pwsh firmware/scripts/build.ps1
    pwsh firmware/scripts/build.ps1 -Clean -BuildType RelWithDebInfo
#>
[CmdletBinding()]
param(
    [ValidateSet('Release', 'RelWithDebInfo', 'Debug')]
    [string]$BuildType = 'Release',

    [switch]$Clean,

    [string]$ToolchainPrefix
)

$ErrorActionPreference = 'Stop'

# 빌드 타깃은 SHT30 단일 보드(sht30_fw).
$Target = 'sht30_fw'

# ── 경로 산출 (스크립트 위치 기준, cwd 무관) ─────────────────────────────────
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$FwRoot    = Split-Path -Parent $ScriptDir            # .../firmware
$BuildDir  = Join-Path $FwRoot 'build'
$Toolchain = Join-Path $FwRoot 'cmake/arm-none-eabi-toolchain.cmake'

Write-Host "==== SHT30 STM32F407 펌웨어 빌드 ====" -ForegroundColor Cyan
Write-Host "  firmware root : $FwRoot"
Write-Host "  build dir     : $BuildDir"
Write-Host "  build type    : $BuildType"
Write-Host "  target        : $Target"

# ── 사전 점검: 필수 도구 ─────────────────────────────────────────────────────
function Assert-Tool([string]$name) {
    if (-not (Get-Command $name -ErrorAction SilentlyContinue)) {
        throw "필수 도구를 찾을 수 없습니다: $name (PATH 확인)"
    }
}
Assert-Tool 'cmake'
Assert-Tool 'ninja'

# 툴체인 컴파일러 존재 확인(접두 override 미지정 시 PATH 에서 arm-none-eabi-gcc).
if (-not $ToolchainPrefix) {
    if (-not (Get-Command 'arm-none-eabi-gcc' -ErrorAction SilentlyContinue)) {
        throw "arm-none-eabi-gcc 를 PATH 에서 찾을 수 없습니다. -ToolchainPrefix 로 지정하세요."
    }
}

# ── 폐쇄망 가드: third_party 벤더링 확인 ─────────────────────────────────────
$ThirdParty = Join-Path $FwRoot 'third_party'
if (-not (Test-Path $ThirdParty)) {
    throw @"
third_party 가 없습니다(폐쇄망 빌드 전 벤더링 필요).
networked 빌드 머신에서 먼저 실행하세요:
    pwsh firmware/scripts/vendor.ps1
"@
}

# ── 클린 빌드 ────────────────────────────────────────────────────────────────
if ($Clean -and (Test-Path $BuildDir)) {
    Write-Host "  (clean) 기존 빌드 디렉터리 삭제: $BuildDir" -ForegroundColor Yellow
    Remove-Item -Recurse -Force $BuildDir
}

# ── Configure (Ninja + 툴체인) ───────────────────────────────────────────────
$cfgArgs = @(
    '-S', $FwRoot
    '-B', $BuildDir
    '-G', 'Ninja'
    "-DCMAKE_TOOLCHAIN_FILE=$Toolchain"
    "-DCMAKE_BUILD_TYPE=$BuildType"
)
if ($ToolchainPrefix) {
    $cfgArgs += "-DTOOLCHAIN_PREFIX=$ToolchainPrefix"
}

Write-Host "`n[1/2] cmake configure …" -ForegroundColor Green
& cmake @cfgArgs
if ($LASTEXITCODE -ne 0) { throw "cmake configure 실패 (exit $LASTEXITCODE)" }

# ── Build ────────────────────────────────────────────────────────────────────
$buildArgs = @('--build', $BuildDir, '--target', $Target)

Write-Host "`n[2/2] cmake build ($Target) …" -ForegroundColor Green
& cmake @buildArgs
if ($LASTEXITCODE -ne 0) { throw "빌드 실패 (exit $LASTEXITCODE)" }

# ── 산출물 요약 ──────────────────────────────────────────────────────────────
Write-Host "`n==== 빌드 완료. 산출물 ====" -ForegroundColor Cyan
Get-ChildItem -Path $BuildDir -Recurse -Include '*.elf', '*.bin', '*.hex', '*.map' `
    -ErrorAction SilentlyContinue |
    ForEach-Object {
        '{0,12:N0}  {1}' -f $_.Length, $_.FullName
    } | Write-Host
