#!/bin/bash

# Configuration by env:
#  - GIT_BASEURL - base url of git repos
#  - GIT_PREFIX - whose repo to clone
#  - GIT_SUFFIX - git component dir suffix (default .git)
#  - COMPONENT - component to clone
#  - BRANCH - git branch
#  - NO_CHECK=1 - disable signed tag checking
#  - CLEAN=1 - remove previous sources (use git up vs git clone)
#  - FETCH_ONLY=1 - fetch sources but do not merge
#  - IGNORE_MISSING=1 - exit with code 0 if remote branch doesn't exists
#  - GIT_REMOTE=<remote-name> - use "remote" from git configuration instead of
#    explicit URL
#  - REPO=dir - specify repository directory, component will be guessed based
#    on basename

set -e
[ "$DEBUG" = "1" ] && set -x

[ -n "$REPO" ] && COMPONENT="`basename $REPO`"

# Special case for qubes-builder itself
[ "$REPO" == "." ] && COMPONENT="builder"

[ -z "$COMPONENT" ] && { echo "ERROR: COMPONENT not set!"; exit 1; }

[ -z "$REPO" ] && REPO="$COMPONENT"

url_var="GIT_URL_${COMPONENT//-/_}"

if [ -n "$GIT_URL" ]; then
    GIT_URL="$GIT_URL"
elif [ -n "${!url_var}" ]; then
    GIT_URL="${!url_var}"
else
    GIT_URL=$GIT_BASEURL/$GIT_PREFIX$COMPONENT$GIT_SUFFIX
fi

# Override GIT_URL with GIT_REMOTE if given
[ -n "$GIT_REMOTE" ] && GIT_URL=$GIT_REMOTE

branch_var="BRANCH_${COMPONENT//-/_}"

if [ -n "${!branch_var}" ]; then
    BRANCH="${!branch_var}"
fi

fresh_clone=0
echo "-> Updating sources for $COMPONENT..."
echo "--> Fetching from $GIT_URL $BRANCH..."
if [ "$REPO" == "." -o -d $REPO -a "$CLEAN" != '1' ]; then
    cd $REPO
    if ! git fetch -q $GIT_URL --tags $BRANCH; then
        if [ "$IGNORE_MISSING" == "1" ]; then exit 0; else exit 1; fi
    fi
    VERIFY_REF=FETCH_HEAD
    cd - >/dev/null
else
    rm -rf $REPO
    if ! git clone -n -q -b $BRANCH $GIT_URL $REPO; then
        if [ "$IGNORE_MISSING" == "1" ]; then exit 0; else exit 1; fi
    fi
    VERIFY_REF=HEAD
    fresh_clone=1
fi

elementIn () {
  # $1: element to check for
  # $2: array to check for element in
  local element
  for element in "${@:2}"; do [[ "$element" == "$1" ]] && return 0; done
  return 1
}

verify=true
if [ "$NO_CHECK" == "1" ] || elementIn "$COMPONENT" ${NO_CHECK[@]}; then
    echo "--> $COMPONENT has NO_CHECK enabled"
    echo "--> NOT Verifying tags..."
    verify=false
fi

if [ "$verify" == "true" ]; then
    echo "--> Verifying tags..."
    if ! $(dirname $0)/verify-git-tag $REPO $VERIFY_REF; then
        # if verfication failed, remove fetched content to make sure we'll not
        # use it
        if [ "$fresh_clone" -eq 1 ]; then
            rm -rf "$REPO"
        else
            rm -f "$REPO"/.git/FETCH_HEAD
        fi
        exit 1
    fi
fi

if [ "$FETCH_ONLY" == "1" ]; then
    exit 0
fi

CURRENT_BRANCH=`cd $REPO; git branch | sed -n -e 's/^\* \(.*\)/\1/p'`
if [ "$CURRENT_BRANCH" != "$BRANCH" -o "$VERIFY_REF" == "HEAD" ]; then
    pushd $REPO &> /dev/null
    red="`echo -e '\033[1;31m'`"
    green="`echo -e '\033[1;32m'`"
    normal="`echo -e '\033[0;0m'`"
    if [ -n "`git name-rev --name-only $BRANCH 2> /dev/null`" ]; then
        echo "--> Switching branch from $CURRENT_BRANCH branch to ${green}$BRANCH${normal}"
        git checkout $BRANCH || exit 1
    else
        echo -e "--> Switching branch from $CURRENT_BRANCH branch to new ${red}$BRANCH${normal}"
        git checkout FETCH_HEAD -b $BRANCH || exit 1
    fi
    popd &> /dev/null
fi

if [ "$VERIFY_REF" == "FETCH_HEAD" ]; then
    echo "--> Merging..."
    pushd $REPO &> /dev/null
    git merge --commit -q FETCH_HEAD
    popd &> /dev/null
fi

echo
