#!/bin/bash

tmp=/tmp/.git-effort
above='0'
color=

#
# get date for the given <commit>
#

date() {
  git log --pretty='format: %ai' $1 | cut -d ' ' -f 2
}

#
# hide cursor
#

hide_cursor() {
  printf '\033[?25l'
}

#
# show cursor
#

show_cursor() {
  printf '\033[?25h'
  printf '\033[m\n'
  exit 1
}

#
# get active days for the given <commit>
#

active_days() {
  date $1 | uniq | awk '
    { sum += 1 }
    END { print sum }
  '
}

#
# set 'color' based on the given <num>
#

color_for() {
  test $1 -gt 10 && color='33'
  test $1 -gt 25 && color='33;1'
  test $1 -gt 50 && color='93'
  test $1 -gt 75 && color='93;1'
  test $1 -gt 100 && color='31'
  test $1 -gt 125 && color='31;1'
  test $1 -gt 150 && color='91'
  test $1 -gt 200 && color='91;1'
}

#
# compute the effort of the given <file ...>
#

effort() {
  for file in $@; do
    commits=`git log --oneline $file | wc -l`
    color='90'

    # ignore <= --above
    test $commits -le $above && continue

    # commits
    color_for $commits
    len=${#file}
    dot="."
    f_dot=$file
    i=0 ; while test $i -lt $((45-$len)) ; do
      f_dot=$f_dot$dot
      i=$(($i+1))
    done

    printf "  \033[${color}m%s %-10d" $f_dot $commits

    # active days
    active=`active_days $file`
    color_for $active
    printf "\033[${color}m %d\033[0m\n" $active
  done
}

#
# print heading
#

heading() {
  echo
  printf "  %-45s %-10s %s\n" 'file' 'commits' 'active days'
  echo
}

#
# output sorted results
#

sort_effort() {
  clear
  echo
  heading
  cat $tmp | sort -rn -k 2
}

# --above <n-commits>

if test "$1" = "--above"; then
  shift; above=$1
  shift
fi

# [file ...]

if test $# -ge 1; then
  files=$@
else
  files=`git ls-files`
fi

# hide cursor

hide_cursor
trap show_cursor INT

# loop files

heading
effort $files | tee $tmp && sort_effort
echo

show_cursor
