param(
    [Parameter(Mandatory = $true)]
    [ValidateSet('scalar', 'baseline', 'avx2')]
    [string]$Profile
)

$ErrorActionPreference = 'Stop'
$build = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\out\build\msvc-$Profile"))
$targets = @('uc_demo', 'uc_tests', 'uc_bench', 'uc_focused_bench')

function Require-Flag(
    [string]$Command,
    [string]$Pattern,
    [string]$Description,
    [string]$Context
) {
    if ($Command -notmatch $Pattern) {
        throw "${Profile}/${Context}: missing $Description"
    }
}

function Reject-Flag(
    [string]$Command,
    [string]$Pattern,
    [string]$Description,
    [string]$Context
) {
    if ($Command -match $Pattern) {
        throw "${Profile}/${Context}: unexpected $Description"
    }
}

function Assert-ProfileCommand(
    [string]$Command,
    [string]$Context
) {
    $optimizationFlags = @([regex]::Matches(
        $Command,
        '(?i)(?:^|\s)/(?:O1|O2|Od|Ox)(?=\s|$)'
    ) | ForEach-Object { $_.Value.Trim() })
    if ($optimizationFlags.Count -ne 1 -or $optimizationFlags[0] -ine '/O2') {
        $actual = if ($optimizationFlags.Count -eq 0) { 'none' } else { $optimizationFlags -join ', ' }
        throw "${Profile}/${Context}: expected exactly /O2, found $actual"
    }

    $runtimeFlags = @([regex]::Matches(
        $Command,
        '(?i)(?:^|\s)/(?:MDd?|MTd?)(?=\s|$)'
    ) | ForEach-Object { $_.Value.Trim() })
    if ($runtimeFlags.Count -ne 1 -or $runtimeFlags[0] -ine '/MT') {
        $actual = if ($runtimeFlags.Count -eq 0) { 'none' } else { $runtimeFlags -join ', ' }
        throw "${Profile}/${Context}: expected exactly /MT, found $actual"
    }

    Reject-Flag $Command '(?i)(?:^|\s)/GL(?=\s|$)' '/GL (IPO/LTO must be off)' $Context

    switch ($Profile) {
        'scalar' {
            Require-Flag $Command '(?i)(?:^|\s)/d2Qvec-(?=\s|$)' '/d2Qvec-' $Context
            Require-Flag $Command '(?i)(?:^|\s)/Qvec-report:1(?=\s|$)' '/Qvec-report:1' $Context
            Require-Flag $Command '(?i)(?:^|\s)/Oi-(?=\s|$)' '/Oi-' $Context
            Require-Flag $Command '(?i)UC_SIMD_PROFILE_SCALAR=1' 'UC_SIMD_PROFILE_SCALAR=1' $Context
            Require-Flag $Command '(?i)_USE_STD_VECTOR_ALGORITHMS=0' '_USE_STD_VECTOR_ALGORITHMS=0' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/arch:AVX\S*' '/arch:AVX*' $Context
            Reject-Flag $Command '(?i)UC_SIMD_PROFILE_(?:BASELINE|AVX2)=1' 'a foreign SIMD profile definition' $Context
        }
        'baseline' {
            Require-Flag $Command '(?i)UC_SIMD_PROFILE_BASELINE=1' 'UC_SIMD_PROFILE_BASELINE=1' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/(?:d2Qvec-|Qvec-)(?=\s|$)' 'vectorizer-disable flag' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/Oi-(?=\s|$)' '/Oi-' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/arch:AVX\S*' '/arch:AVX*' $Context
            Reject-Flag $Command '(?i)_USE_STD_VECTOR_ALGORITHMS=0|UC_SIMD_PROFILE_(?:SCALAR|AVX2)=1' 'a foreign SIMD profile definition' $Context
        }
        'avx2' {
            Require-Flag $Command '(?i)UC_SIMD_PROFILE_AVX2=1' 'UC_SIMD_PROFILE_AVX2=1' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/(?:d2Qvec-|Qvec-)(?=\s|$)' 'vectorizer-disable flag' $Context
            Reject-Flag $Command '(?i)(?:^|\s)/Oi-(?=\s|$)' '/Oi-' $Context
            Reject-Flag $Command '(?i)_USE_STD_VECTOR_ALGORITHMS=0|UC_SIMD_PROFILE_(?:SCALAR|BASELINE)=1' 'a foreign SIMD profile definition' $Context

            $architectureFlags = @([regex]::Matches(
                $Command,
                '(?i)(?:^|\s)/arch:\S+'
            ) | ForEach-Object { $_.Value.Trim() })
            if ($architectureFlags.Count -ne 1 -or $architectureFlags[0] -ine '/arch:AVX2') {
                $actual = if ($architectureFlags.Count -eq 0) {
                    'none'
                } else {
                    $architectureFlags -join ', '
                }
                throw "${Profile}/${Context}: expected exactly /arch:AVX2, found $actual"
            }
        }
    }
}

$validatedCommands = 0
foreach ($target in $targets) {
    $releaseDirectory = Join-Path $build "$target.dir\Release"
    if (-not (Test-Path -LiteralPath $releaseDirectory -PathType Container)) {
        throw "${Profile}/${target}: missing Release build directory $releaseDirectory"
    }

    $logs = @(Get-ChildItem -LiteralPath $releaseDirectory -Recurse `
        -Filter 'CL.command.1.tlog' -File)
    if ($logs.Count -ne 1) {
        throw "${Profile}/${target}: expected one compiler command log, found $($logs.Count)"
    }

    # MSBuild writes command tlogs as UTF-16LE without a reliable BOM.
    $commandLines = @(Get-Content -LiteralPath $logs[0].FullName -Encoding Unicode |
        Where-Object { $_ -and -not $_.StartsWith('^') })
    if ($commandLines.Count -eq 0) {
        throw "${Profile}/${target}: compiler command log contains no commands"
    }

    for ($index = 0; $index -lt $commandLines.Count; ++$index) {
        $context = if ($commandLines.Count -eq 1) {
            $target
        } else {
            "$target command $($index + 1)"
        }
        Assert-ProfileCommand $commandLines[$index] $context
        ++$validatedCommands
    }
}

Write-Host "Build flag audit passed for ${Profile}: $validatedCommands Release compiler command(s) across $($targets.Count) targets."
