#!/usr/bin/env bash
#
# git-out
#
# License: MIT
# Copyright (c) 2012 Lennart C. L. Kats

set -e

QUIET=
NO_FETCH=
FETCHED=
FETCHERS=
ALL=

for P in "$@"; do
  case $P in
    -q)
      QUIET=-q
      shift ;;
    -f)
      NO_FETCH=-f
      shift ;;
    -a|--all)
      ALL=-a
      shift ;;
  esac
done

MYBRANCH=
SELECTION="$@"

if echo "$SELECTION" | grep -iE 'head|local' >/dev/null \
  || ([ "$SELECTION" == "" ] && ! [ "$ALL" ]); then
  SELECTION=`git-get-branch`
  MYBRANCH=1
fi

BRANCHES=`git branch --list $SELECTION | sed 's/\* //'`

BRANCH=`git-get-branch 2>/dev/null` &&
  BRANCHES="`git-get-branch` `echo "$BRANCHES" | grep -Ev "^$BRANCH\$"`" || :

clearLine() {
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '                                                            '
    echo -ne '                                                            '
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
    echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'
}

if [ ! $NO_FETCH ]; then
  git fetch -q origin &
  FETCHER=$!
fi

while [ ! -e .git ] && [ "`pwd`" != "/" ]; do
  cd ..
done
GIT_OUT_CACHE=`cat .git/git-out-cache 2>/dev/null || echo`

PRINTED_FIRST=
for BRANCH in $BRANCHES; do
  if echo $BRANCH | grep '^_' >/dev/null || [ "$BRANCH" == "(no" ] ||
     [ "$BRANCH" == "branch)" ]; then
    continue
  fi
  REVISION=`git rev-parse $BRANCH`
  if [[ "$GIT_OUT_CACHE" =~ "$REVISION" ]]; then
    continue
  elif ! git log -1 --oneline origin/$BRANCH &> /dev/null; then
    LOG=`git log --oneline --first-parent $BRANCH --not --remotes=origin`
    [ $PRINTED_FIRST ] && echo || PRINTED_FIRST=1
    if [ "$LOG" == "" ]; then
      echo -e "\033[09;32m$BRANCH\033[00m (empty)"
    else
      if [ ! $MYBRANCH ]; then
        echo -e "\033[01;32m$BRANCH\033[00m"
      fi
      if [ $QUIET ]; then
        echo "`echo "$LOG" | wc -l` commit(s)"
      else
        echo "$LOG"
      fi
    fi
  elif [ "`git log origin/$BRANCH..$BRANCH 2>/dev/null`" != "" ]; then
    [ $PRINTED_FIRST ] && echo || PRINTED_FIRST=1
    LOG=`git log --oneline --first-parent $BRANCH --not --remotes=origin`
    if [ ! $MYBRANCH ]; then
      echo -e "\033[01;32m$BRANCH\033[00m"
    fi
    if [ $QUIET ]; then
      echo "`echo "$LOG" | wc -l` commit(s)"
    else
      echo "$LOG"
    fi
  elif [ "`git log origin/master..$BRANCH 2>/dev/null`" != "" ]; then
    FETCHERS="$FETCHERS $BRANCH"
  else
    echo $REVISION >> .git/git-out-cache
  fi
done

if [ "$FETCHERS" != "" ]; then
  if [ ! $NO_FETCH ]; then
    [ $PRINTED_FIRST ] && echo || PRINTED_FIRST=1
    if which git-list-pull-requests &>/dev/null && [ "$GITHUB_REPOS" ]; then
      git-list-pull-requests -a >/tmp/.git-out-requests &
      PULLS=$!
    else
      echo >/tmp/.git-out-requests &
      PULLS=$!
    fi
    echo -n "Fetching info for `echo "$FETCHERS" | wc -w | grep -oE '[0-9]+'` remote branch(es)... "
    SUCCESS=
    wait $FETCHER
    clearLine
    FETCHED=1
  fi 
  PRINTED_FIRST=
  for BRANCH in $FETCHERS; do
    if [ "`git log origin/master..$BRANCH 2>/dev/null`" != "" ]; then
      if [ ! $NO_FETCH ]; then
        wait $PULLS
        PULL_REQUESTS=`cat /tmp/.git-out-requests`
      fi
      if [ "`git log origin/master..$BRANCH 2>/dev/null`" != "" ]; then
        [ $PRINTED_FIRST ] && echo || PRINTED_FIRST=1
        if [ ! $NO_FETCH ] && echo "$PULL_REQUESTS" | grep "^$BRANCH\$" > /dev/null; then
          echo -e "$BRANCH (in pull request)"
          git is-current -f -q $BRANCH
        else
          echo -e "\033[01;32m$BRANCH\033[00m (unmerged in origin/master)"
        fi
      fi
    fi
  done
fi
