#!/bin/bash

function print_usage(){
    cat <<END
Usage: $0 [-b bugs] [-d work_dir] [-m message] [-t updateType] <srpm> [scope1 [scope2 ....]]

  This command automates the release process from SRPM to bodhi pushing.

Parameters:
    -b bugs: The list of bug this update fixed. Split with ','.

    -d work_dir: The work directory. Default is current directory.

    -m message: Message used as commit message.
       If not specified, then use the latest changelog text.
       (i.e. rpm -qp --queryformat "%{CHANGELOGTEXT}" <srpm>)

    -t updateType: Update type. Valid values:
       [bugfix|security|enhancement|newpackage].
       Default: 
         newpackage: if this package does not exist in bodhi
         enhancement: if the latest change log item has "Enhancement:"
         bugfix: for everything else.   

    srpm: SRPM file to be scratch-built with koji.

    scopes: Fedora and/or EPEL branche to release. 
      Multiple values are allowed.
      Valid values:
          rawhide: Release rawhide.

          fedora: Release active fedora releases, including Rawhide.

          fedora_1: Build the latest released fedora release.
              This is one release eariler than rawhide.

          fedora_2: Build the second latest released fedora releases.
              This is two releases eariler than rawhide.

          f22 f21 ...: Build the specified fedora releases.

          epel: Build the active EPEL releases.

          epel_1: Build the latest released EPEL releases.

          epel_2: Build the second latest released EPEL releases.

          epel7 el6 ... : The EPEL releases to be built.

         If scopes is not specified, then it builds all active Fedora  
	 (including rawhide) and EPEL releases in fedpkg branches.

Environment Variables:
    FEDPKG_DIR
        The directory that this program should work on.
	If -d is not specified, this program will use the value as
	work directory.

    BODHI_USER
        Bodhi username. If not specified, it uses environment variable
       	LOGNAME.


END
}

# is target been built in koji
# Valid target example: cmake-fedora-1.4.0-1.fc21
function is_target_built(){
    target=$1
    $KOJI_CMD buildinfo $target | grep -qcs -i "State: COMPLETE"
}

# is package exists in bodhi
# Valid target example: cmake-fedora
function is_package_new_in_bodhi(){
    package=$1
    if $BODHI_CMD $package | grep -qcs $package;then
	return 1
    else
	return 0
    fi
}

function try_command(){
    if ! "$@" ;then
	ret=$?
	echo "cmake-fedora-fedpkg: Failed to $@" > /dev/stderr
	exit $ret
    fi
}

# is target in bodhi
# Valid target example: cmake-fedora-1.4.0-1.fc21
function is_target_in_bodhi(){
    target=$1
    $BODHI_CMD "${target}" | grep -qcs -i "Update ID" > /dev/null
}

function is_update_enhancement(){
    echo $CHANGELOGTEXT | grep -qcs -e "Enhancement:"
}

function contains_element () {
    local e
    for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
    return 1
}


SCRIPT_DIR=$(readlink -f `dirname $0`)
for d in Modules cmake-fedora/Modules ${SCRIPT_DIR}/../Modules /usr/share/cmake/Modules;do
    if [ -r $d/CmakeFedoraScript.cmake ];then
	CMAKE_FEDORA_SCRIPT_CMAKE=$d/CmakeFedoraScript.cmake
    fi
done
if [ -z "${CMAKE_FEDORA_SCRIPT_CMAKE}" ];then
    echo "[Error] CmakeFedoraScript.cmake is not found" > /dev/stderr
    exit -2
fi

CMAKE_FEDORA_KOJI_CMD=${SCRIPT_DIR}/cmake-fedora-koji
if [ ! -x ${CMAKE_FEDORA_KOJI_CMD} ];then
    echo "[Error] cmake-fedora-koji is not found" > /dev/stderr
    exit -2
fi

for cmd in fedpkg bodhi koji git rpm ;do
    cfsOpts=(-D cmd=find_program verbose_level=1  )
    ## Workaround for Bug 1115136 otherwise el7 won't work
    case $cmd in
	bodhi )
	    cfsOpts+=( -D "names=bodhi;client.py" -D "paths=/usr/bin/bodhi" )
	    ;;
	*)
	    cfsOpts+=( -D "names=$cmd")
	    ;;
    esac
    cmdPath=`cmake "${cfsOpts[@]}" -P ${CMAKE_FEDORA_SCRIPT_CMAKE}`
    if [ $? -ne 0 ];then
	exit $?
    fi

    VAR_NAME=`tr a-z A-Z <<<$cmd`_CMD
    eval "$VAR_NAME=$cmdPath"
done


if [ $# = 0 ]; then
    print_usage
    exit 0
fi


BODHI_USER=${BODHI_USER:=$LOGNAME}
echo "BODHI_USER=$BODHI_USER"

WORK_DIR=${FEDPKG_DIR:-$PWD}
MSG=
BODHI_OPTS=()
UPDATE_TYPE=

while getopts "hb:d:m:t:" opt;do
    case $opt in
	h)
	    print_usage
	    exit 0
	    ;;
	b )
	    BUGS=$OPTARG
	    ;;
	d )
	    WORK_DIR=$OPTARG
	    ;;
	m )
	    MSG=$OPTARG
	    ;;
	t )
	    UPDATE_TYPE=$OPTARG
	    ;;
	* )
	    ;;
	    
    esac
done
shift $((OPTIND-1)) 

SRPM=$1
shift

if [[ -z $SRPM ]];then
    print_usage
    exit 1
else
    SRPM=`readlink -f $SRPM`
fi

if [[ ! -r "$SRPM" ]];then
    echo "[Fatal] Failed to read $SRPM" > /dev/stderr
    exit 2
fi

if [[ -n "$BUGS" ]];then
    BODHI_OPTS+=(--bugs $BUGS)
fi

if [[ ! -w $WORK_DIR ]];then
    if ! mkdir -p $WORK_DIR; then
	echo "$WORK_DIR is not writable." > /dev/stderr
	exit 2
    fi
fi
echo "WORK_DIR=$WORK_DIR" > /dev/stderr

CHANGELOGTEXT=`$RPM_CMD -qp --queryformat "%{CHANGELOGTEXT}" $SRPM`
echo "CHANGELOGTEXT=$CHANGELOGTEXT" > /dev/stderr

if [[ -z "$MSG" ]];then
    MSG=$CHANGELOGTEXT
fi

NAME=`$RPM_CMD -qp --queryformat "%{NAME}" $SRPM`
echo "NAME=$NAME" > /dev/stderr

## NVR here does not include release tag,
##  (e.g. cmake-fedora-2.0.0-1)
NVR=`$RPM_CMD -qp --queryformat "%{NAME}-%{VERSION}-%{RELEASE}" $SRPM | sed -e 's/\.fc[0-9]*$//' | sed -e 's/\.el[0-9]*$//'`

if [[ -z "$UPDATE_TYPE" ]];then
    if  is_package_new_in_bodhi $NAME; then
	UPDATE_TYPE=newpackage
    elif is_update_enhancement; then
	UPDATE_TYPE=enhancement
    else
	UPDATE_TYPE=bugfix
    fi
fi
echo "UPDATE_TYPE=$UPDATE_TYPE" > /dev/stderr

cd $WORK_DIR
if [[ ! -r $NAME ]];then
    try_command ${FEDPKG_CMD} clone $NAME
fi

if [[ ! -x $NAME ]];then
    echo "Failed to change to $WORK_DIR/$NAME" > /dev/stderr
    exit 3
fi

cd $NAME
echo "Pulling $NAME..." > /dev/stderr
try_command ${FEDPKG_CMD} pull

## Interset between existing and koji fedpkg branches
FEDPKG_BRANCHES_KOJI=(`$CMAKE_FEDORA_KOJI_CMD git-branch $@ | xargs ` )
FEDPKG_BRANCHES_EXISTING=(` $FEDPKG_CMD switch-branch | grep origin | sed -e  's|^\s*origin/||' | xargs` )
declare -a FEDPKG_BRANCHES=()
for activeBranch in "${FEDPKG_BRANCHES_KOJI[@]}"; do
    if contains_element "${activeBranch}" "${FEDPKG_BRANCHES_EXISTING[@]}";then
	FEDPKG_BRANCHES+=(${activeBranch})
    fi
done
echo -n "Branches to process:"
(IFS=' ' echo "${FEDPKG_BRANCHES[@]}")
bodhiPushList=
first=

for b in "${FEDPKG_BRANCHES[@]}";do
    if [[ -z "$first" ]];then
	first=$b
    fi
    
    koji_buildinfo_suffix=`$CMAKE_FEDORA_KOJI_CMD koji-buildinfo-suffix $b`

    target="$NVR.$koji_buildinfo_suffix"
    try_command ${FEDPKG_CMD} switch-branch $b
    echo -n "Has $target already been built in koji? ... " > /dev/stderr
    if is_target_built $target ;then
	echo "yes, skip this." > /dev/stderr
    else
	echo "no, start building." > /dev/stderr
	if [[ $first = $b ]];then
	    try_command ${FEDPKG_CMD} import $SRPM
	    try_command ${FEDPKG_CMD} commit -m "$MSG"
	else
	    try_command $GIT_CMD merge $first
	fi
	try_command ${FEDPKG_CMD} push
	echo "Building $NVR.$bodhi_branch" > /dev/stderr
	try_command ${FEDPKG_CMD} build
    fi

    bodhi_branch=`$CMAKE_FEDORA_KOJI_CMD bodhi-branch $b`

    if [[ -n "$bodhi_branch" ]];then
	echo -n "Has $target already in bodhi? ... " > /dev/stderr
	if is_target_in_bodhi $target ; then
	    echo "yes, skip this." > /dev/stderr
	else
	    echo "no, will push it." > /dev/stderr
	    bodhiPushList="$bodhiPushList $NVR.$bodhi_branch"
	fi
    fi
done

if [[ -n "$bodhiPushList" ]];then
    try_command ${BODHI_CMD} -n "${BODHI_OPTS[@]}" -t $UPDATE_TYPE -u $BODHI_USER -N "$CHANGELOGTEXT" -R testing $bodhiPushList
else
    echo "Nothing to push to bodhi." > /dev/stderr
fi

