#!/bin/sh
# Brutal Router for Unix Tools - https://brut.sh
set -eu


# Find ourselves
OLDENV="$(export -p)"
SELF="$(realpath "$0")"
NAME="${0##*/}"
PROGRAM_NAME="${SELF##*/}"
ROOT="${SELF%/*/*}"


# Set up the environment
LIB="$ROOT/lib/$NAME"
LIBEXEC="$ROOT/libexec"
SHARE="$ROOT/share/$NAME"
VENDOR="$SHARE/vendor"

PATH="$LIB:$LIBEXEC:$VENDOR:$PATH"
export SELF

USAGE="<COMMAND>"
unset VERSION


# ---
# Define shared helpers

error() {
  NAME="${1##*/}"
  shift

  printf "%s: " "$(invocation)"
  printf "%s\n" "$@"
  return 1
} >&2

usage() {
  if [ $# -eq 0 ]; then
    set -- "$NAME" "${USAGE:-}" "commands: $(flatten commands)"
  fi

  NAME="${1##*/}"
  shift

  printf "usage: %s " "$(invocation)"
  printf "%s\n" "$@"
  return 1
} >&2

version() {
  printf "%s %s\n" "$PROGRAM_NAME" "$VERSION"
}

# ---

commands() {
  executables | sed -e "s/^.*\/$NAME-//" | sort
}

executables() {
  for ns in $(namespaces "$NAME-"); do
    set -- "$@" \! -name "$ns-*"
  done

  searchpath -name "$NAME-*" "$@" | awk -F / '!a[$NF]++'
}

flatten() {
  "$@" | { tr "\n" " "; printf "\n"; }
}

invocation() {
  { printf "%s\n" "$PROGRAM_NAME"; namespaces; } \
    | sort -r | awk -v name="$NAME" \
      'index(name, $0 "-") == 1 { name = $0 " " substr(name, length($0) + 2) }
       END { print name }'
}

namespaces() {
  searchpath -type l -name "${1:-$PROGRAM_NAME-}*" \
    -exec sh -c '[ "$0" = "$(realpath "$1")" ] 2>/dev/null' "$SELF" {} \; \
    | sed -e "s/^.*\///" | sort -u
}

resolve() {
  case "${1:-}" in
    *-* ) executables -name "$NAME-$1" ;;
    ?* ) searchpath -name "$NAME-$1" | head -n 1
  esac | grep .
}

searchpath() {
  { IFS=:
    dirs=
    set -- \) -o -prune "$@"
    for dir in $PATH; do
      [ -d "$dir" ] || continue
      set -- -o -path "$dir" "$@"
      dirs="$dirs:$dir"
    done
    set -- ${dirs#:} \( \! -name '*' "$@"
    unset IFS
  } 2>/dev/null

  find -H "$@" 2>/dev/null \
    \( -perm -001 -o -perm -010 -o -perm -100 \) \
    \( -type f -o -type l \) \
    \! -name "?*--?*" \
    -print || true
}

unenv() {
  exec env -i sh -euc 'eval "$1"; shift; exec "$@"' "$0" "$OLDENV" "$@"
}

# ---


# Load _init.sh, if it exists
if [ -r "$LIB"/_init.sh ]; then
  . "$LIB"/_init.sh
fi


# Rewrite `--version` to `--- version`
if [ $# -eq 1 ] && [ -n "${VERSION:-}" ] && [ "$1" = "--version" ]; then
  set -- --- version
fi


# When invoked as `--- <COMMAND> ...`, run that exact command and exit
if [ "${1:-}" = "---" ]; then
  [ $# -gt 1 ] || usage
  shift
  "$@"
  exit
fi


# Scan the argument list to find the command name
COMMAND=
args=
index=0

for arg; do
  index=$((index+1))
  case "$arg" in
    -* ) ;;
    ?*--?* ) [ -n "$COMMAND" ] || usage ;;
    * )
      if [ -z "$COMMAND" ]; then
        COMMAND="$arg"
        continue
      fi
  esac
  args="$args"' "${'"$index"'}"'
done


# Match the command name to an executable in the current namespace;
# if one exists, exec it
if executable="$(resolve "$COMMAND")"; then
  eval "set --$args"
  exec "$executable" "$@"
fi


# No matching executable; load _unhandled.sh, if it exists
if [ -r "$LIB"/_unhandled.sh ]; then
  . "$LIB"/_unhandled.sh
fi


# No matching command or no command specified
if [ -n "$COMMAND" ]; then
  error "$0" "$COMMAND: command not found" || exit 127
fi

usage