#! /bin/sh

noise_set() { # set a variable
  case "$1" in
    (-q|--quiet) echo=: ; shift ;;
    (*) echo=echo ;;
  esac
  case $# in
    (0) ## print all noise variables
      env | sed -rn '
        s/^noise_([[:alnum:]_]+)=(.*)$/\1 = \2/p
      ' | sort
    ;;
    (1) ## print value the specified variable
      eval "echo \"$1 = \$noise_$1\""
    ;;
    (*) ## set the specified variable
      if echo "$1" | grep -q '[^[:alnum:]_]' ; then
        fail invalid variable name "$1"
        return 23
      fi
      eval "old=\"\$noise_$1\""
      if test "x$old" = "x$2" ; then
        eval "$echo \"$1 is already $2\""
      elif test -z "$old" ; then
        eval "export noise_$1='$2' ; $echo \
\"$1 set to $2\""
      else
        eval "export noise_$1='$2' ; $echo \
\"$1 changed from $old to $2\""
      fi
      ## write variable to $env
      if grep -q "^$1=" "$env" ; then
        sed -ri "s'^($1)=(.*)\$'\1=\'$2\''" $env
      else
        echo "$1='$2'" >>$env
      fi
    ;;
  esac
}

noise_unset() { # unset a variable
  case "$1" in
    (-q|--quiet) echo=: ; shift ;;
    (*) echo=echo ;;
  esac
  case $# in
    (1) ## 
      unset "noise_$1"
      sed -ni "/^$1=/!p" $env
    ;;
    (*)
      fail "broken commandline: $@"
    ;;
  esac
}

noise_quit() { # exit
  echo "Good bye!"
  exit
}

fail() {
  echo "FAIL: $*"
  return 23
}

cleanup() {
  kill $jobs
  rm -f $linefeed $env
  rmdir /tmp/noise/$$ 2>/dev/null
  rmdir /tmp/noise 2>/dev/null
}

exec 2>&1
qname="`readlink -f "$0"`"
dirname="`dirname "$qname"`"
export HOME='/home/shack'
if test -d "$dirname/modules" ; then
  export NOISE_PATH="${NOISE_PATH+$NOISE_PATH:}$dirname/modules"
  export NOISE_PATH="${NOISE_PATH+$NOISE_PATH:}$HOME/noise/modules"
fi
mkdir -p /tmp/noise/$$
linefeed="/tmp/noise/$$/linefeed"
env="/tmp/noise/$$/environment"
trap cleanup EXIT
mkfifo $linefeed
touch $env
##
##
##
readline() {
  { read && echo "$REPLY" ; } | sed -rn "
    s/[']//g
    s/~%/\n/g
    s/([^\\])([#<>])/\1\\\\\2/g
    s:^/([a-z_]+)([[:space:]]+(.*))?$:command=\1; args='\3';:p;t
    s@^([[:alnum:]_/+-]+):[[:space:]]*(.*)@command=lang; args='\1 \2';@p;t
    s@^\![[:space:]]*(.*)@command=play; args='\1';@p;t
    s:.*:command='$noise_default_command'; args='&';:p;t
  "
}
##
##
##
while echo -n "$noise_prompt" && eval "`readline`" ; do
  ## modcall
  for dir in `echo "$NOISE_PATH" | tr : \ ` ; do
    module="$dir/$command"
    if test -x "$module" ; then
      shift
      eval 'NOISE="$0" NOISE_pid="$$" NOISE_linefeed="$linefeed" "$module"' "$args"
      continue 2
    fi
  done
  ## funcall
  if type noise_$command &>/dev/null ; then
    eval 'noise_$command' "$args"
    continue
  fi
  ##
  fail unknown command "$command"
done <$linefeed &
jobs="${jobs+$jobs }`jobs -p`"
##
##
##
cat<<EOF
Welcome to 23.shack version 0.9 beta 4 \
commit `
  cd $dirname &&
  git log -n 1 | head -n 1 | cut -d\  -f 2 | dd count=23 bs=1 2>/dev/null
`...

## Motto Of The Day\

Join the 23.shack-dev-team, we've got `
  sloccount $dirname/* |
  sed -rn '
    s/.*\(SLOC\)[[:space:]]*=[[:space:]]*([0-9]+)$/\1/p
  '` SLOC, `
  { ls $dirname/modules/ ; ls ~shack/noise/modules/ ; } | sort | uniq | wc -l
  ` mods,
`grep ^- $dirname/TODO | wc -l`+ TODOs and drive the irregular Hackathon @shackspace.
Follow http://twitter.com/shackspam FTW!

## Hints\

Start your telnet session with rlwrap for MAXIMUM profit.
Get online-help with /help.

EOF
# TODO: MOTD-candidates:
#twitter: #shackspam
#mail: shockspasm@googlemail.com
#irc: freenode/#shackspace
#afk: @shackspace
##
##
##
exec >>$linefeed
##
##
##
echo '/set -q default_command espeak'
echo '/set -q prompt "READY.~%"'
##
##
##
while read ; do
  case $REPLY in
    (/quit) echo /quit ; exit ;; 
    (*) tr \; \\n | grep . ;;
  esac<<EOF
$REPLY
EOF
done
#### end of file.