#!/usr/bin/env bash
# Control for temporal signatures as data.
#
# Unlike the other checks this one is read BY the compiler, not after it: the
# El-level return type decides which runtime wrapper to emit, and that is
# dispatch, not adjudication. What moved out is the data.
set -uo pipefail
ELC="${1:?usage: temporal_signatures.sh <elc>}"
LANG_DIR="${2:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT; F=0
chk(){ [ "$2" = "$3" ] && printf '  ok    %s\n' "$1" || { printf '  FAIL  %s\n    expected %s got %s\n' "$1" "$2" "$3"; F=$((F+1)); }; }
cd "$LANG_DIR"

printf 'fn main() {\n    let a = now()\n    let b = el_duration_from_nanos(5)\n    let c = a + b\n    println("ok")\n}\n' > "$W/i.el"
chk "an inferred Instant + Duration dispatches to the typed wrapper" \
    "1" "$("$ELC" "$W/i.el" 2>/dev/null | grep -c el_instant_add_dur)"
chk "with no signature file, the type is unknown and it does not" \
    "0" "$(EL_SIGNATURES=/nonexistent "$ELC" "$W/i.el" 2>/dev/null | grep -c el_instant_add_dur)"

printf 'fn main() {\n    let a: Instant = now()\n    let b: Instant = now()\n    let c: Instant = a + b\n    println("x")\n}\n' > "$W/b.el"
chk "Instant + Instant is still refused" \
    "1" "$("$ELC" "$W/b.el" 2>/dev/null | grep -c 'TIME_TYPE_ERROR: Instant + Instant')"

printf 'fn main() {\n    let a: Instant = now()\n    let d: Duration = el_duration_from_nanos(1)\n    let c: Instant = a + d\n    println("x")\n}\n' > "$W/g.el"
chk "Instant + Duration is allowed" \
    "0" "$("$ELC" "$W/g.el" 2>/dev/null | grep -c TIME_TYPE_ERROR)"

echo; echo "  4 assertions, $((4-F)) passed, $F failed"; exit $F
