$path_root = split-path -Path $PSScriptRoot -Parent

# --- Toolchain Executable Paths ---
$compiler  = 'clang'
$linker    = 'lld-link.exe'

# https://clang.llvm.org/docs/ClangCommandLineReference.html
$flag_c23                          = '-std=c23'
$flag_compile                      = '-c'
$flag_debug                        = '-g'
$flag_define                       = '-D'
$flag_exceptions_disabled		   = '-fno-exceptions'
$flag_diagnostics_absolute_paths   = '-fdiagnostics-absolute-paths'
$flag_include                      = '-I'
$flag_linker                       = '-Wl,'
$flag_link_mapfile 		           = '/MAP:'
$flag_link_win_subsystem_console   = '/SUBSYSTEM:CONSOLE'
$flag_link_win_machine_64          = '/MACHINE:X64'
$flag_link_win_debug               = '/DEBUG'
$flag_link_win_pdb 			       = '/PDB:'
$flag_link_win_path_output         = '/OUT:'
$flag_link_no_incremental          = '/INCREMENTAL:NO'
$flag_no_optimization 		       = '-O0'
$flag_path_output                  = '-o'
$flag_wall 					       = '-Wall'
$flag_nologo 			           = '/nologo'

$path_build = join-path $path_root 'build'
if ( -not(test-path -Path $path_build) ) {
	new-item -ItemType Directory -Path $path_build
}

push-location $path_build

# --- File Paths ---
$unit_name      = "attempt_1"
$unit_source    = join-path $path_root "attempt_1\main.c"
$object         = join-path $path_build "$unit_name.obj"
$binary         = join-path $path_build "$unit_name.exe"
$pdb            = join-path $path_build "$unit_name.pdb"
$map            = join-path $path_build "$unit_name.map"

# --- Stage 1: Compile C to Object ---
write-host "Stage 1: Compiling C to Object"
$compiler_args = @()
$compiler_args += ($flag_define + 'BUILD_DEBUG=1')
$compiler_args += $flag_debug
$compiler_args += $flag_wall
$compiler_args += $flag_c23
$compiler_args += $flag_no_optimization
$compiler_args += $flag_diagnostics_absolute_paths
$compiler_args += $flag_exceptions_disabled
$compiler_args += ($flag_include + (join-path $path_root "attempt_1"))
# $compiler_args += "-nostdlib"
# $compiler_args += "-ffreestanding"
$compiler_args += $flag_compile
$compiler_args += $flag_path_output, $object
$compiler_args += $unit_source

$compiler_args | ForEach-Object { Write-Host $_ }
$stage1_time = Measure-Command { & $compiler $compiler_args }
write-host "Compilation took $($stage1_time.TotalMilliseconds)ms"
write-host

# --- Stage 2: Linking ---
write-host "Stage 2: Linking"
$linker_args = @()
$linker_args += $flag_nologo
$linker_args += $flag_link_win_machine_64
$linker_args += $flag_link_no_incremental
$linker_args += ($flag_link_win_path_output + $binary)
$linker_args += $flag_link_win_debug
$linker_args += $flag_link_win_pdb + $pdb
$linker_args += $flag_link_mapfile + $map
$linker_args += $flag_link_win_subsystem_console
# $linker_args += "/nodefaultlib"
$linker_args += "kernel32.lib"
$linker_args += "user32.lib"
$linker_args += "gdi32.lib"
$linker_args += $object

$linker_args | ForEach-Object { Write-Host $_ }
$linking_time = Measure-Command { & $linker $linker_args }
write-host "Linking took $($linking_time.TotalMilliseconds)ms"
write-host

if ($LASTEXITCODE -eq 0) {
    write-host "Build Successful! Run $binary manually to see the GUI." -ForegroundColor Green
}

Pop-Location
