#
# Iceberg
# http://cgrayson.github.io/iceberg/
#
# (c) Chris Grayson
#
ICEBERG_VERSION=1.9.10
USAGE="$0: Usage: $0 [ -d du_input_filename | -l (use local JavaScript) | -p (plain text output) | -t tmp_dir ]"
GEN_DATE=`date +"%m-%d-%Y"`

CDN_URL=http://cgrayson.github.io/iceberg
ICEBERG_JS_FILE=iceberg.js
ICEBERG_CSS_FILE=iceberg.css
ICEBERG_JS=${CDN_URL}/javascripts/${ICEBERG_JS_FILE}
ICEBERG_CSS=${CDN_URL}/stylesheets/${ICEBERG_CSS_FILE}
num_divs=0

ICEBERG_INPUT_FILE="iceberg_input.txt"
ICEBERG_TEMP_FILE="iceberg_input.tmp"
DU_INPUT_FILE=""
HTML=1
TMPDIR="."

while getopts ":d:lpt:" option
do
  case $option in
    d ) DU_INPUT_FILE="$OPTARG"
      if [ ! -f "$DU_INPUT_FILE" ]
      then
        echo "Error: du input file '$DU_INPUT_FILE' not found"
        echo "$USAGE"
        exit 3
      fi
      ;;
    l ) # Use local JavaScript & CSS (developer use)
      ICEBERG_JS=$ICEBERG_JS_FILE
      ICEBERG_CSS=$ICEBERG_CSS_FILE
      ;;
    p ) HTML=0
      ;;
    t ) TMPDIR="$OPTARG"
      if [ ! -d "$TMPDIR" ]
      then
        echo "Error: tmp dir '$TMPDIR' not found"
        echo "$USAGE"
        exit 3
      fi
      ;;
    * ) echo "Unknown option $option"
        echo $USAGE
        exit 3
      ;;
  esac
done

# shift past all dash-options
shift $(($OPTIND - 1))

if [ -n "$1" ]
then
  ROOT=${1%%/}  # strip rightmost "/", if present
  shift
else
  ROOT="."
fi

if [ ! -d "$ROOT" ]
then
  echo "Error: root dir '$ROOT' not found"
  echo $USAGE
  exit 4
fi

create_input_file() {
  if [ -z "$DU_INPUT_FILE" ]
  then
    DU_INPUT_FILE="$TMPDIR/$ICEBERG_TEMP_FILE"
    du -h "$ROOT" > $DU_INPUT_FILE
    RM_DU_INPUT=1 # clean up this tmp file later (only if not provided by user)
  fi

  # wish I knew how to use a variable to pipe commands to...
  echo "reverse utility test" | tail -r > /dev/null 2>&1
  if [ $? -eq 0 ]
  then
    cat "$DU_INPUT_FILE" | tail -r > "$ICEBERG_INPUT_FILE"
  else
    echo "reverse utility test" | tac > /dev/null 2>&1
    if [ $? -eq 0 ]
    then
      cat "$DU_INPUT_FILE" | tac > "$ICEBERG_INPUT_FILE"
    fi
  fi

  if [ "$RM_DU_INPUT" = 1 ]
  then
    rm "$DU_INPUT_FILE"
  fi
}

indent() {
  # save up to 35% in filesize by skipping indentation in HTML output
  if [ "$HTML" -eq 0 ]
  then
    i=$1
    while [ $i -gt 0 ]
    do
      echo -n "$2  "
      let i=$i-1
    done
  fi
  echo $3
}

# $1 - previous level number
# $2 - current level number
# $* - row record (size string, tab, path string)
rowprint() {
  prevlevel=$1
  currlevel=$2
  shift 2

  args="$*"
  size="${args%%[	]*}"    # get first field (i.e., trim off leftmost whitespace and following)
  filename="${args##*/}"  # get final file/dirname (i.e., trim up to & incl. rightmost "/")

  if [ "$HTML" -eq 1 ]
  then
    if [ "$currlevel" -gt "$prevlevel" ]
    then
      indent $prevlevel "" "<div class='folder'><button class='btn btn-small enabled' ><i class='icon-folder-close'></i></button> <span class='size'>$size</span> $filename </div><div class='child'>"
      let num_divs=$num_divs+1
    else
      indent $prevlevel "" "<div class='folder'><button class='btn btn-small disabled' ><i class='icon-folder-close'></i></button> <span class='size'>$size</span> $filename </div>"
    fi
  else
    indent $prevlevel "|" "$*"
  fi
}

endrows() {
  if [ "$HTML" -eq 1 ]
  then
    end_prev=$1
    currlevel=$2
    while [ "$end_prev" -gt "$currlevel" ]
    do
      indent $end_prev "" "</div>"
      let num_divs=$num_divs-1
      let end_prev=$end_prev-1
    done
  fi
}

dirsize() {
  IFS="
"
  prevrec='xxx'
  prevlevel=-1

  create_input_file

  for rec in `cat $ICEBERG_INPUT_FILE`
  do
    levelstr1="${rec##*[	]}"          # get the 2nd field, from the leftmost tab to EOL
    levelstr2="${levelstr1//[^\/]/}"   # remove all characters but the "/"s
    level="${#levelstr2}"              # count the remaining "/"s

    if [ "$prevlevel" -ge 0 ]
    then
      rowprint $prevlevel $level $prevrec
      
      if [ "$level" -lt "$prevlevel" ]
      then
        endrows $prevlevel $level
      fi
    fi

    prevlevel=$level
    prevrec="$rec"
  done

  level=`echo "$rec" | cut -f2 | tr -dc "/" | wc -c`

  if [ "$level" -lt "$prevlevel" ]
  then
    endrows $prevlevel $level
  fi

  rowprint $prevlevel $level $prevrec

  while [ "$num_divs" -gt 0 ]
  do
    endrows 9 8
  done

  rm "$ICEBERG_INPUT_FILE"
}

if [ "$HTML" -eq 1 ]
then
  cat <<HERE_DOC
  <!DOCTYPE html>
  <html><head>
  <!-- generated by iceberg.sh v.${ICEBERG_VERSION} -->
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-combined.min.css" rel="stylesheet">
  <link href="$ICEBERG_CSS" rel='stylesheet' />
  <script src='https://code.jquery.com/jquery-2.2.4.min.js' type='text/javascript' charset='utf-8'></script>
  <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/js/bootstrap.min.js"></script>
  <script src="$ICEBERG_JS" type='text/javascript' charset='utf-8'></script>
  <title>Iceberg: $ROOT</title>
  </head><body>

  <div class='filebrowser well'>

  <div class="btn-group" data-toggle="buttons-radio" id="size-buttons">
    <button class="btn" id="btn1mb">1 MB</button>
    <button class="btn" id="btn10mb">10 MB</button>
    <button class="btn" id="btn100mb">100 MB</button>
    <button class="btn active" id="btn1gb">1 GB</button>
    <button class="btn" id="btn10gb">10 GB</button>
    <button class="btn" id="btn100gb">100 GB</button>
  </div>

  <div id="about">generated on $GEN_DATE by <a href="http://cgrayson.github.io/iceberg/">Iceberg v.${ICEBERG_VERSION}</a></div>
  <div id="loading" class="label">Loading...</div>

  <div id='folders'>
HERE_DOC
fi

dirsize

if [ "$HTML" -eq 1 ]
then
  echo "  </div>"
  echo "  </div>"
  echo "</body></html>"
fi
