hook(){
  test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; } 
  logger "$ hook $*"
  cmd=$1
  shift 
  test -d ~/hook.d/$cmd && {
    find -L ~/hook.d/$cmd/ -type f -executable -maxdepth 1 | while read hook; do 
      logger "    |+ hook $hook $*"
      { $hook "$@" || true; } |  awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
    done
  } | tee -a ~/hook.d/log.txt
}

alert(){
  test -z "$1" && { echo "usage: alert <title> <message>"; return 0; } 
  title=$1
  test -z "$1" || shift
  msg="$*"
  printf "%s \033[0m%s\n" "$title" "$msg"
  hook alert $title "$msg" 
}

confirm(){
  test -z "$1" && { echo "usage: confirm <question>"; return 0; } 
  read -p "$(printf "\033[0m")[?] $1 [y/n] $(printf "\033[0m")" y
  test $y = "y" && echo true && return 0
  test $y = "y" || echo false 
  hook confirm $1 $y
}

prompt(){
  test -z "$1" && { echo "usage: prompt <question> [answer_default]"; return 0; } 
  test -n "$2" && answer="[$2] " && answer_fallback="$2"
  read -p "$(printf "\033[0m")[?] $1: $answer $(printf "\033[0m")" answer
  test -z "$answer" && answer="$answer_fallback"
  echo "$answer"
  hook prompt $1 $answer
}

console(){
  js 'return '$1
  printf "\n"
}

# usage: require <url|file>
#
# info: adds javascript/css url/script to DOM 
require(){
  test -n "$1" || { echo "usage: require <url>"; exit 0; }
  file=$(basename "$1")
  ext="${file/*\./}"

  case $ext in

    js|css)
      js '(async () => {
        await AFRAME.utils.require({"'$file'": "'$1'"})
      })(); return ""'
      ;;

    glb|gltf|obj|usdz|fbx)
      require 'https://xrfragment.org/dist/xrfragment.aframe.js'
      sleep 1.5
      echo "<a-entity xrf='$1'></a-entity>" >> /root/index.html 
      ;;

    sh)
      js '
        fetch('$1')
        .then( (res) => res.text() )
        .then( (text) => console.log(text) ) 
      '
      ;;

    *)
      alert $ext "extension is not supported (yet)"
      ;;

  esac

}

# usage: man <topic>
#
# info: simple manual viewer
man(){
  test "$1" = xrsh && {
    cat /root/manual.md | less
  }
}
help(){ man xrsh; }

# usage: infinite ./runmydaemon 
#
# info: will run daemon forever (restarts when quit)
infinite(){
  while sleep 1s; do 
    "$@"
  done
}

# usage: wait_for sleep 5s
#
# info: will print dots while waiting for process to end
wait_for(){
  dotting(){ while sleep 1s; do printf "."; done; }
  dotting &
  PID=$!
  "$@"
  kill -9 $PID
  printf "\n"
}