#!/usr/bin/bash
#
# git-dude - Git commit notifier
# https://github.com/ku1ik/git-dude
#
# Copyright (C) 2011 Marcin Kulik <https://ku1ik.com/>
#
# Distributed under the GNU General Public License, version 3.0.

set -e

interval=$(git config dude.interval || true)
interval=${interval:-60}
app_name=$(basename $0)

export LC_ALL=C # make sure git talks english

if [[ $(git config dude.notify-command) ]]; then
  notify_cmd=$(git config dude.notify-command)
elif [ $(which notify-send 2>/dev/null) ]; then
  notify_cmd='notify-send -i "$ICON_PATH" "$TITLE" "$DESCRIPTION"'
elif [ $(which terminal-notifier 2>/dev/null) ]; then
  notify_cmd='terminal-notifier -title "$TITLE" -message "$DESCRIPTION"'
elif [ $(which growlnotify 2>/dev/null) ]; then
  notify_cmd='growlnotify -n "$app_name" --image "$ICON_PATH" -m "$DESCRIPTION" "$TITLE"'
elif [ $(which kdialog 2>/dev/null) ]; then
  notify_cmd='kdialog --icon $ICON_PATH --title "$TITLE" --passivepopup "$DESCRIPTION"'
elif [ $(which notify 2>/dev/null) ]; then
  notify_cmd='notify --type information --icon "$ICON_PATH" --group "Git Commit" --title "$TITLE" "$DESCRIPTION"'
fi

function dudenotify() {
  local ICON_PATH="$1"
  local TITLE="$2"
  local DESCRIPTION="$3"

  if [ -n "$notify_cmd" ]; then
    eval $notify_cmd
  fi

  date "+%x %X"
  echo "$TITLE"
  if [ -n "$DESCRIPTION" ]; then
    echo "$DESCRIPTION"
  fi
  echo
}

if [[ $(git config dude.screensaver-command) ]]; then
  screensaver_cmd=$(git config dude.screensaver-command)
elif [ $(which gnome-screensaver-command 2>/dev/null) ]; then
  screensaver_cmd='LANG=C gnome-screensaver-command -q | grep -q "is active"'
fi

function screensaver() {
  if [ -n "$screensaver_cmd" ]; then
    eval $screensaver_cmd
    if [[ $? != 0 ]]; then
      return 1
    fi
  fi

  # if we cannot be certain, default to saying screensaver is not
  # active in order to run git-dude on every loop
  return 0
}

[[ -d "$1" ]] && cd $1

while true; do
  if ! screensaver; then
    for dir_name in *; do
      if [[ -d "$dir_name" && $(cd "$dir_name"; git rev-parse --git-dir 2>/dev/null) ]]; then

        if [[ $(cd "$dir_name"; git config dude.ignore) == true ]]; then
          continue
        fi

        repo_name=$(basename "$dir_name" .git)
        cd "$dir_name"

        remote=$(git config dude.remote || true)
        changes=$(git fetch $remote 2>&1 | grep -F -- '->' | sed 's/^ [+*=!-] //')

        icon_path=$(git config dude.icon || true)
        icon_path=${icon_path:-`pwd`/icon.png}
        icon_path=${icon_path// /\\ } # escape spaces before eval
        eval icon_path=$icon_path # to expand ~

        while read -r line; do
          case $line in
            *..*)
              commit_range=$(echo "$line" | awk '{ print $1 }')
              branch_name=$(echo "$line" | awk '{ print $2 }')
              commit_messages=$(git log $commit_range --pretty=format:'%s (%an)')
              notify_message="New commits in $repo_name/$branch_name"
              if [ -n "$remote" ]; then
                  notify_message="${notify_message} at $remote"
              fi
              dudenotify $icon_path "$notify_message" "$commit_messages"
              ;;
            *new\ branch*)
              branch_name=$(echo "$line" | awk '{ print $3 }')
              notify_message="New branch $repo_name/$branch_name"
              if [ -n "$remote" ]; then
                  notify_message="${notify_message} at $remote"
              fi
              dudenotify $icon_path "$notify_message" ""
              ;;
            *new\ tag*)
              tag_name=$(echo "$line" | awk '{ print $3 }')
              notify_message="New tag $repo_name/$tag_name"
              if [ -n "$remote" ]; then
                  notify_message="${notify_message} at $remote"
              fi
              dudenotify $icon_path "$notify_message" ""
              ;;
          esac
        done <<< "$changes"

        cd - &>/dev/null
      fi
    done
  fi
  if [ "$interval" = "0" ]; then    
     exit 0
  else
     sleep $interval
  fi 
done
