{{ header_comment }}

{% from "_helpers.j2" import safe_name, safe_attr, board_name, safe_board_name, get_vendor_id, get_device_id %}


# Guard against re-sourcing this master script
if {[info exists ::build_master_running]} return
set ::build_master_running 1

# Prevent GUI dialogs in batch mode
set_param gui.enableXmsgs 0

# Close any existing project to avoid conflicts
catch {close_project -quiet}

# Enhanced Vivado Build Script with Error Reporting
set logfile [open "build_console.log" a]
proc log {msg} {
    global logfile
    puts $logfile "[clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"] $msg"
    flush $logfile
    puts $msg
}

log "=========================================="
log "PCILeech Firmware Build Process"
log "=========================================="
log "Device: {{ get_vendor_id(device_config, device, config_space, vendor_id_int) }}:{{ get_device_id(device_config, device, config_space, device_id_int) }} (Class: {{ device_config.class_code }})"
log "Board: {{ safe_name(board) }}"
log "Build started: [clock format [clock seconds]]"
log ""

# Error tracking variables
set build_errors 0
set build_warnings 0
set failed_scripts [list]
set error_details [list]
set warning_details [list]
set error_report_file "vivado_error_report.txt"

# Color codes for terminal output (if supported) - declare all globally
set color_red "\033\[91m"
set color_yellow "\033\[93m"
set color_green "\033\[92m"
set color_blue "\033\[94m"
{{ header_comment }}

{% from "_helpers.j2" import safe_name, get_vendor_id, get_device_id %}

# Guard against re-sourcing this master script
if {[info exists ::build_master_running]} return
set ::build_master_running 1

# Batch-friendly defaults and clean start
set_param gui.enableXmsgs 0
catch {close_project -quiet}

# Basic logging (console + file)
set logfile [open "build_console.log" a]
proc log {msg} {
    global logfile
    set ts [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"]
    puts $logfile "$ts $msg"
    flush $logfile
    puts $msg
}

set script_dir [file dirname [info script]]

log "=========================================="
log "PCILeech Firmware Build"
log "Device: {{ get_vendor_id(device_config, device, config_space, vendor_id_int) }}:{{ get_device_id(device_config, device, config_space, device_id_int) }}"
log "Board: {{ safe_name(board) }}"
log "Started: [clock format [clock seconds]]"
log "=========================================="

# Fail-fast helpers
proc die {msg} {
    log "ERROR: $msg"
    catch {close_project -quiet}
    global logfile
    close $logfile
    exit 1
}

proc require_file {path} {
    if {![file exists $path]} {
        die "Missing required script: $path"
    }
}

proc run_step {relpath} {
    global script_dir
    set full [file normalize [file join $script_dir $relpath]]
    require_file $full
    log "--> Sourcing $relpath"
    if {[catch {source $full} err]} {
        die "Step failed ($relpath): $err"
    }
}

# Deterministic step order
set steps [list \
    "01_project_setup.tcl" \
    "02_ip_config.tcl" \
    "03_add_sources.tcl" \
    "04_constraints.tcl" \
    "05_synthesis.tcl" \
    "06_implementation.tcl" \
    "07_bitstream.tcl" \
]

set start_ts [clock seconds]
foreach s $steps { run_step $s }

# Minimal artifact check
if {![file exists "pcileech_top.bit"]} {
    die "Bitstream not found: pcileech_top.bit"
}

set kb [format %.1f [expr {[file size "pcileech_top.bit"] / 1024.0}]]
log "Bitstream generated: pcileech_top.bit (${kb} KB)"

set elapsed [expr {[clock seconds] - $start_ts}]
set mm [expr {$elapsed / 60}]
set ss [expr {$elapsed % 60}]
log "Completed in ${mm}m ${ss}s"
log "=========================================="

catch {close_project -quiet}
close $logfile
exit 0