#!/usr/bin/env bash
###
### a simple complement to bild which only deals with launching repls
###
### > repl [opts] <target..>
###
### Starts a repl/shell for one or more targets. (Currently, all targets must
### have the same extension for this to work.) Repls started with this script
### should bind to `localhost:$PORT`.
###
### Options:
###   --bash   start bash instead of the target language repl
help() {
    sed -rn 's/^### ?//;T;p' "$0"
}
if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then
    help
    exit 1
fi
##
  set -e
  CMD=
  if [[ "$1" == "--bash" ]]; then
    CMD="bash"
    shift
  fi
  targets="${*:?}"
  json=$(bild --plan "${targets[@]}")
  mapfile -t langdeps < <(jq --raw-output '.[].langdeps | select(length > 0) | join("\n")' <<< "$json")
  mapfile -t sysdeps < <(jq --raw-output '.[].sysdeps | select(length > 0) | join("\n")' <<< "$json")
  mapfile -t rundeps < <(jq --raw-output '.[].rundeps | select(length > 0) | join("\n")' <<< "$json")
  exts=$(jq --raw-output '.[].namespace.ext' <<< "$json" | sort | uniq)
  packageSet=$(jq --raw-output '.[].packageSet' <<< "$json")
  module=$(jq --raw-output '.[].mainModule' <<< "$json")
  BILD="(import ${CODEROOT:?}/Biz/Bild.nix {})"
  declare -a flags=(--packages "$BILD.pkgs.pkg-config")
  for lib in "${sysdeps[@]}"; do
    flags+=(--packages "$BILD.pkgs.${lib}")
  done
  for lib in "${rundeps[@]}"; do
    flags+=(--packages "$BILD.pkgs.${lib}")
  done
  case $exts in
    C)
      flags+=(--packages "$BILD.pkgs.gcc")
      command="bash"
      ;;
    Hs)
      if [ -z ${var+PORT} ]; then
        echo "warn:  repl:  ghci does not support binding to a port"
      fi
      flags+=(--packages "$BILD.bild.haskell.ghcWith (h: with h; [${langdeps[*]}])")
      command=${CMD:-"ghci -i${CODEROOT:?} -ghci-script ${CODEROOT:?}/.ghci ${targets[@]}"}
      ;;
    Scm)
      for lib in "${langdeps[@]}"; do
        flags+=(--packages "$BILD.guile-${lib}")
      done
      flags+=(--packages "$BILD.guile")
      command=${CMD:-"guile -L ${CODEROOT:?} -C ${CODEROOT:?}/_/int --r7rs --listen=${PORT:-37146}"}
      ;;
    Lisp)
      flags+=(--packages "$BILD.bild.$packageSet (p: with p; [asdf swank ${langdeps[*]}])")
      command=${CMD:-"sbcl --eval '(require :asdf)' --eval '(require :swank)' --eval '(swank:create-server :port ${PORT:-4005})' --load $targets"}
      ;;
    Rs)
      flags+=(--packages "$BILD.nixpkgs.rustc")
      command=bash
      ;;
    Py)
      langdeps+=("mypy")
      flags+=(--packages ruff)
      flags+=(--packages "$BILD.bild.python.pythonWith (p: with p; [${langdeps[*]}])")
      PYTHONPATH=$CODEROOT:$PYTHONPATH
      pycommand="python -i $CODEROOT/Biz/Repl.py $module ${targets[*]}"
      command=${CMD:-"$pycommand"}
      ;;
    *)
      echo "unsupported targets: ${targets[*]}"
      exit 1
      ;;
  esac
##
  nix-shell "${flags[@]}" --command "$command"
##