#!/usr/bin/env bash
## VSCode task wrapper for the A-Shell compiler (Linux/WSL build: compil, the
## ELF binary -- the counterpart of compil.ps1, which drives compil.exe on
## Windows). Echoes the exact command line and the compiler's stdout/stderr
## into the task terminal, and passes the compiler's native error lines
## ("file,line,message,code") straight through so the problemMatcher in
## tasks.json can populate the PROBLEMS tab.
## See the "linux" override of "command" in tasks.json:
##   "linux": { "command": "${workspaceFolder}/aux-files/compil.sh" }
##
## The following arguments are sent to this script by VSCode when you activate
## the Task (A-Shell Compile) -- identical contract to compil.ps1:
##   $1 = filename, see ${file} (or ${command:ashell.buildTarget}) in tasks.json
##   $2 = working dir, see ${workspaceFolder} in tasks.json
##   $3 = optional full path to the miame.ini to compile against, see
##        ${command:ashell.miameIni} in tasks.json. When given, this is the SAME
##        ini the language extension resolved for the file being built (the
##        resource-scoped ashell.miameIniPath setting, so each folder of a
##        multi-root workspace can compile against its own device table). When
##        omitted (older tasks.json), falls back to $2/miame.ini.
##
### NOTES:
### 1. Without the third argument, -ini defaults to $2/miame.ini (set by VSCode
###    from your workspace). If your workspace folder is not also your A-Shell
###    working directory you'll need a copy of miame.ini there -- or point
###    ashell.miameIniPath at the real one. A trimmed-down ini (only the
###    devices/ersatz defs that matter during development) loads faster in the
###    LSP.
### 2. compil (the Linux/WSL build) ships inside the A-Shell extension and is
###    copied to  ${XDG_DATA_HOME:-$HOME/.local/share}/ashell/compil  on
###    activation, with its executable bit set -- one copy per user, kept up to
###    date alongside the rest of the extension. $cmd below defaults to that
###    location; edit it if you'd rather point at a compil of your own.
### 3. MIAME env var: compil's DevPPN / ersatz resolution for `++include
###    device:file[p,pn]` and `++include ersatz:file` only kicks in when $MIAME
###    is set (a native path in ++include always works regardless). A full
###    A-Shell login sets it; a bare compil in WSL/CI does not, so this script
###    defaults it to the directory holding the miame.ini -- the same thing
###    `%MIAME%` expands to. Already have MIAME set (normal on a real A-Shell
###    box)? This leaves it untouched. Override per-workspace via the task's
###    "options": { "env": { "MIAME": "/your/miame" } } if the ini lives
###    somewhere other than the MIAME root.

set -u

toCompile="${1:-}"
workingDirectory="${2:-}"
miameIni="${3:-}"

if [ -z "$miameIni" ]; then
    miameIni="$workingDirectory/miame.ini"
fi

## Enable compil's device/PPN/ersatz include resolution (see NOTE 3). Only set
## when the caller hasn't already -- a real A-Shell environment's MIAME wins.
export MIAME="${MIAME:-$(dirname "$miameIni")}"

## $cmd = location of the compil binary; $cmd_args = compiler switches (mirror
## compil.ps1 -- keep the two in sync).
cmd="${XDG_DATA_HOME:-$HOME/.local/share}/ashell/compil"
cmd_args=(-ini "$miameIni" -rc -i -w:4000 -x:2 -px -a -n -lf -b -l -so -z "$toCompile")

echo "Compiling: $toCompile"
echo "Command:   $cmd ${cmd_args[*]}"
echo "MIAME:     $MIAME"
echo

## compil writes to a pipe here (not a tty), so it emits plain \n. We then
## strip any stray CR and squeeze the compiler's runs of blank lines to one
## (it pads its output with blank lines after "Phase 1"/"Phase 2"/each error;
## through a pty's \n->\r\n that reads as annoying double-spacing).
outFile="$(mktemp)"
errFile="$(mktemp)"
"$cmd" "${cmd_args[@]}" >"$outFile" 2>"$errFile"
status=$?

tr -d '\r' < "$outFile" | sed 's/[[:space:]]*$//' | cat -s
tr -d '\r' < "$errFile" | sed 's/[[:space:]]*$//; s/^/stderr: /'
rm -f "$outFile" "$errFile"

## Unlike the Windows build, the Linux compil does NOT echo its parseable
## "file,line,message,code" error lines to stdout under -so -- it only writes
## them to <source>.lst (the -b switch). Echo that file so the tasks.json
## problemMatcher, which scans terminal output, can still populate PROBLEMS.
lstFile="${toCompile%.*}.lst"
if [ -s "$lstFile" ]; then
    echo
    tr -d '\r' < "$lstFile" | sed 's/[[:space:]]*$//'
fi

echo
echo "compil exited with code $status"
exit $status
