#!/bin/bash -e

[[ -n $DEBUG ]] && set -x

repo_path="$1" # user/repo_name
tmp_dir=/tmp/gh_releases
rm -rf $tmp_dir
mkdir -p $tmp_dir

fatal() { echo -e "\n[FATAL] $@" 1>&2; exit 1; }
warning() { echo -e "[WARNING] $@" 1>&2; }

usage() {
    cat >&2 <<EOF
Usage: $(basename $0) <user>/<repo>

Env Vars:
    # used for github api
    GITHUB_USER
    GITHUB_USER_TOKEN

    # retain temp files and set x if set
    DEBUG

    # omit tags or releases in output respectively if set
    NO_TAGS
    NO_RELEASES

Note: Setting GITHUB_USER and GITHUB_USER_TOKEN environment variables are
      recommended. If not set, multipage results may be unreliable.
EOF
}

if [[ -z "$repo_path" ]]; then
    usage
    fatal "user/repo not provided!"
fi
if [[ -z "$GITHUB_USER" ]]; then
    warn="GITHUB_USER not set!"
fi
if [[ -z "$GITHUB_USER_TOKEN" ]]; then
    warn="$warn GITHUB_USER_TOKEN not set!"
fi
if [[ -n "$GITHUB_USER" ]] && [[ -n "$GITHUB_USER_TOKEN" ]]; then
    USER="-u $GITHUB_USER:$GITHUB_USER_TOKEN"
else
    warning $warn "Authentication won't be used."
    USER=""
fi

if [[ -n "$NO_TAGS" ]]; then
    warning "omitting tags (NO_TAGS is set)"
fi
if [[ -n "$NO_RELEASES" ]]; then
    warning "omitting releases (NO_RELEASES is set)"
fi

echo -n "Fetching releases from github for '$repo_path'... " 1>&2

get_page() {
    url=$1
    key=$2
    page=$3
    tmp_file=$(mktemp $tmp_dir/XXXX.tmp)
    curl $USER -b /tmp/cookies.txt -c /tmp/cookies.txt -s "${url}?page=${page}&per_page=100" > $tmp_file || true
    if grep "Bad credentials" $tmp_file >/dev/null ; then
        fatal "Bad GitHub credentials"
    else
        grep -oP "\"$key\": \"\\K(.*)(?=\")" $tmp_file
        rm -f $tmp_file
    fi
}

get_all_pages() {
    url=$1
    key=$2
    declare -i page=0
    last_page="$(get_page "$url" "$key" "$page")"

    while [[ -n "$last_page" ]]
    do
        echo "$last_page" >> $tmp_dir/releases
        page+=1
        last_page="$(get_page "$url" "$key" "$page")"
    done
}

[[ -z $NO_RELEASES ]] && get_all_pages "https://api.github.com/repos/${repo_path}/releases" "tag_name"
[[ -z $NO_TAGS ]] && get_all_pages "https://api.github.com/repos/${repo_path}/tags" "name"

echo "Done!" 1>&2
cat $tmp_dir/releases | sort --version-sort --unique
[[ -z $DEBUG ]] && rm -rf $tmp_dir
