#!/bin/bash

set -e
set -u

OLD_PWD=$(pwd)
TAILS_REPO_PATH="$1"

trap cleanup exit

#cd $TAILS_REPO_PATH && git fetch || exit 1
cd $TAILS_REPO_PATH || exit 1

TAILS_BASE_BRANCHES="master devel testing"

cleanup() {
  cd "$OLD_PWD"
}

get_last_release_tag() {
  git tag | egrep -v "jenkins-*|rm" | tail -n 1
}

get_last_release_date() {
  local last_release_tag=$(get_last_release_tag)
  git log -1 --format=%ct $last_release_tag
}


# Takes the $TAILS_BASE_BRANCHES global variable
# Returns the number of base branches (word) it contains.
count_base_branches_number() {
   wc -w <<< $TAILS_BASE_BRANCHES
}

# Takes a base branch
# Returns a list of all branches not merged in this one
list_unmerged_feature_and_bugfix_branches() {
  local base="$1"
  git branch -r --no-merged "origin/${base}" | \
    egrep 'origin/feature|origin/bugfix' | grep -v "feature/jessie"
}

# Takes a datetime in seconds since 1970-01-01 00:00:00 UTC
#   and a branch
# Returns 0 if last commit in branch is newer than datetime, 1
#   otherwise
branch_last_commit_newer_than() {
  local datetime="$1"
  local branch="$2"
  branch_last_commit_date=$(git show --format="%ct" $branch | head -n1)
  [ $branch_last_commit_date -gt $datetime ] || return 1
}

# Takes a branch and a list of all unmerged branches
# Return 0 if the branch is unmerged in all base branches, 1 otherwise
unmerged_in_all_base_branches() {
  local branch="$1"
  local all_branches_since="${2}"
  base_branches_number=$(count_base_branches_number)
  [ $(grep -o "${branch}" <<< "${all_branches_since}" | wc -l) -eq "$base_branches_number" ] || return 1
}

# Takes a datetime in seconds since 1970-01-01 00:00:00 UTC
# Returns a list of unmerged branches in $TAILS_BASE_BRANCHES since then
list_unmerged_branches_since() {
  local datetime="$1"
  local all_branches_since=""
  local keepers=""
  # Collect all unmerged branches in base branches since datetime.
  for base_branch in $TAILS_BASE_BRANCHES; do
    for unmerged_branch in $(list_unmerged_feature_and_bugfix_branches $base_branch); do
      $(branch_last_commit_newer_than $datetime $unmerged_branch) && \
        all_branches_since="$all_branches_since $unmerged_branch"
    done
  done
  # Keep only those which are not merged in all $TAILS_BASE_BRANCHES.
  for branch in $all_branches_since; do
    if unmerged_in_all_base_branches "${branch}" "${all_branches_since}"; then
      grep -qs "${branch}" <<< "${keepers}" || keepers="$keepers $branch"
    fi
  done
  echo "$keepers"
}

LAST_RELEASE_DATE=$(get_last_release_date)

# Example usage
for branch in $(list_unmerged_branches_since $LAST_RELEASE_DATE); do
  branch_last_commit_human_date=$(LC_ALL="C" git show --format="%ci %cr" $branch | head -n1)
  echo "$branch_last_commit_human_date	$branch"
done | sort
