#!/bin/bash
## Modified SPACE LAUNCH, with small fix and added verbose sl -t output.
## File is here temporary, until changes are picked up by cmccabe :)
##
## SPACE LAUNCH - A multi-user take on the classic Unix
##                steam locomotive (sl) prank.
##                Written by cmccabe on the Zaibatsu in 2019.
##
## Questions? Comments? Smart remarks? --> [email protected]
##
## System users should create ~/.vroom files that contain lines within
## the configured limits of length and line numbers.  These .vroom files
## will be fused together using space-age technology and launched into
## orbit whenever this script is run.
## -t, -m and -h switches are explained in the help:
## > sl.sh -h

#########################################################################
## CONFIGURATION VARIABLES
source /home/nop/spacelaunch_nop/config
#source /home/cmccabe/code/space_launch/config

#########################################################################
## VARIABLE INITIALIZATION AND SET-UP STEPS

# stty -echo ## TO DO: HOW TO RE-ENABLE THIS FROM ^C TRAP FUNCTION?
#                      OTHERWISE USER CAN'T SEE THEIR CHARS ECHOED
#                      AFTER THEY KILL THIS SCRIPT.

USER=$(id -run)

# HEIGHT OF TERMINAL WINDOW; USED TO PUSH ROCKET OFF THE SCREEN
TRAILING_SPACE=$(tput lines)
ALTITIDE=0
OLDIFS=$IFS #~Nop, Backing up IFS for later use... or something...

ROCKET_PARTS=$(ls $HOME_DIR/*/.vroom | shuf -n $ROCKET_SIZE)
ROCKET_PARTS=(${ROCKET_PARTS[@]})
[ ${#ROCKET_PARTS[@]} -gt $ROCKET_SIZE ] && ROCKET_PARTS=(${ROCKET_PARTS[@]:1:${ROCKET_SIZE}})
# ^^ CHOOSE $ROCKET_SIZE RANDOM FILES FROM AL ~.vroom FILES

read -r -d '' HELP_TEXT << EOM

================= SPACE LAUNCH (sl) HELP =================

Space Launch reads everyone's .vroom file and concatenates
a random selection of them into an animated rocket.

You can create your own .vroom file.  Just make sure all
of the lines are exactly $VROOM_WIDTH characters long and the file
contains no more than $VROOM_HEIGHT_MAX lines. Make sure the file is
readable by everyone (e.g. chmod ugo+r ~/.vroom) and that
it is located at the top level of your home directory.

Space Launch ignores any .vroom files that don't meet the
file size requirements.  It's not rocket science; so don't
get left on the launch pad!

Command line options:
-t  : Reports if your .vroom file passes or fails spec.
-m  : Prints template .vroom file of size $VROOM_WIDTH x $VROOM_HEIGHT_MAX.
      You can pipe this template into a .vroom file and
      modify it.
-h  : Prints this help message. Duh!

==========================================================
EOM

## CTRL-C TRAP - BLOW UP THE ROCKET WHEN ^c CAUGHT:
ALTITUDE=1 ## INCREMENTS AS ROCKET GOES UP
trap ctrl_c INT
function ctrl_c() {
 # PUSH ROCKET OFF THE SCREEN:
 i=0
 while [ $i -lt $TRAILING_SPACE ]; do
   echo; i=$(($i+1))
 done

 cat $KABOOM

 KABOOM_HEIGHT=$(wc -l "$KABOOM" | cut -d" " -f1);
 if [ "$ALTITUDE" -ge $((TRAILING_SPACE-$KABOOM_HEIGHT)) ] && [ $KABOOM_HEIGHT -lt $TRAILING_SPACE ]; then
   ALTITUDE=$(($TRAILING_SPACE-$KABOOM_HEIGHT))
 elif [ "$ALTITUDE" -le "$KABOOM_HEIGHT" ]; then
   ALTITUDE=0
 fi

 # PRINT EXTRA LINES TO PLACE KABOOM AT CORRECT HEIGHT
 i=0
 while [ $i -lt $ALTITUDE ]; do
   echo
   i=$(($i+1))
 done

#  stty echo ## RE-ENABLE ECHO
 exit
}

#############################################################################
#~Nop VALIDATE_VROOM is called by program itself (also via TEST_VROOM)
#############################################################################
VALIDATE_VROOM () {
 local VERBOSE="${2:-0}"
 if [ -r $1 ]; then
   declare -i i=0
   IFS='' #without setting IFS to '', everything below breaks now :D.
   while read -r line; do  ## lines in file
       let "i+=1"
       if [ "${#line}" = "$VROOM_WIDTH" ]; then
           [ "$VERBOSE" = 1 ] && printf "%02d:%s\tWidth:%d chars. PASS\n" $i $line ${#line};
       else
           [ "$VERBOSE" = 1 ] && printf "%02d:%s\tWidth:%d chars. FAIL\n" $i $line ${#line};
           PASS='fail'
       fi
   done <$1
   IFS=$OLDIFS #Reset IFS to default.

   if [ "$VERBOSE" = 1 ]; then
       echo ""
       echo "=========================================================="
   fi
   # CHECK THAT VROOM FILE IS UNDER HEIGHT LIMIT
   VROOM_HEIGHT=$(($i))
   if [ "$VROOM_HEIGHT" -gt "$VROOM_HEIGHT_MAX" ]; then
       [ "$VERBOSE" = 1 ] && echo "Rocket section height: $VROOM_HEIGHT lines. FAIL";
       PASS='fail'
   else
       [ "$VERBOSE" = 1 ] && echo "Rocket section height: $VROOM_HEIGHT lines. PASS";
   fi
 else
   PASS='fail' # KICK IT OUT IF FILE IS UNREADABLE
 fi
}

#############################################################################
#TEST_VROOM is called via the sl -t option.
#############################################################################
TEST_VROOM () {
 echo
 echo "=========================================================="
 echo "Performing rocket section diagnostics..."
 echo "Analyzing your .vroom file..."
 echo

 TEST_PASS_MSG="PASS! Your .vroom file meets requirements and will be included in future launches."

 read -r -d '' TEST_FAIL_MSG << EOM
FAIL! Your .vroom file does not meet one or more of the
following requirements:

* Each line in the .vroom file must be exactly $VROOM_WIDTH
  characters in length.

* The .vroom file may contain no more than $VROOM_HEIGHT_MAX lines.

==========================================================
EOM

 PASS='pass'
 VALIDATE_VROOM "$HOME_DIR/$USER/.vroom" 1 #~Nop, We call VALIDATE_VROOM in verbose mode.
 echo ""
 if [[ $PASS = 'pass' ]]; then
   echo "PASS! Your .vroom file meets requirements and will be"
   echo "included in future launches.";
   echo "=========================================================="
 elif [[ $PASS = 'fail' ]]; then echo "$TEST_FAIL_MSG";
 else echo "This message indicates that a bug has occured. Please submit a copy of your .vroom accompanied by pitiless mockery to the developer."
 fi
 exit
}

CREATE_VROOM() {
IFS=$OLDIFS #~Nop, just to make sure... not strictly necessary...
for i in $(seq 1 $VROOM_HEIGHT_MAX); do
 for j in $(seq 1 $VROOM_WIDTH); do printf "="; done
 echo
done
}

#########################################################################
## 3, 2, 1 LAUCH!  MAIN PROGRAM FLOW:

[ "$1" = "-h" ] && echo "$HELP_TEXT" && exit
[ "$1" = "-t" ] && TEST_VROOM && exit
[ "$1" = "-m" ] && CREATE_VROOM && exit

# CALCUATE ADDITIONAL PADDING NEEDED RELATIVE TO FLAMES:
PADDING_SIZE=0
IFS=''
while read -r line; do
 [ ${#line} -ge $PADDING_SIZE ] && PADDING_SIZE=${#line}
done <$FLAMES
PADDING_SIZE=$(($PADDING_SIZE-$VROOM_WIDTH))
PADDING_SIZE=$(($PADDING_SIZE/2)) ## TO DO: WHAT IF PAD IS ODD?
PADDING=$(printf '%*s' "$PADDING_SIZE" | tr ' ' " ")

unset PASS

# PRINT THE NOSE CONE
while read -r line; do
 echo "$PADDING$line"
 sleep $SLEEP_TIME
done <$NOSE_CONE

# VALIDATE WIDTH AND HEIGHT OF ROCKET PARTS (FROM USERS)
for i in ${ROCKET_PARTS[@]}; do
 PASS='pass'

 VALIDATE_VROOM $i
 IFS='' #~Nop, Setting IFS to '' again (reset to default by VALIDATE_VROOM
 ## PRINT THE ROCKET PARTS (FROM USERS) IF CORRECT SIZE:
 if [ "$PASS" = 'pass' ]; then
   while read -r line; do  ## lines in file
     echo "$PADDING$line";
     sleep $SLEEP_TIME
   done <$i
 fi

 unset PASS
done

# PRINT THE FLAMES:
while read -r line; do  ## lines in file
 echo "$line";
 ALTITUDE=$((ALTITUDE+1))
 sleep $SLEEP_TIME
done <$FLAMES

# PRINT EXTRA LINES TO KEEP ROCKET MOVING UP
i=0
while [ $i -lt $TRAILING_SPACE ]; do
 echo
 ALTITUDE=$((ALTITUDE+1))
 sleep $SLEEP_TIME
 i=$(($i+1))
done

## stty echo ## RE-ENABLE ECHO SO USERS CAN SEE WHAT THEY TYPE AGAIN
exit