#!/bin/bash

program="${0##*/}"

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
    DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
    SOURCE="$(readlink "$SOURCE")"
    [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done

WORK_DIR_ROOT="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
WORK_DIR_ROOT=${WORK_DIR_ROOT%/*}

SRC_DIR_ROOT=${WORK_DIR_ROOT}
SRC_DIR_BUILD_ROOT=${SRC_DIR_ROOT}/build
SRC_DIR_OUTPUT=${SRC_DIR_BUILD_ROOT}/out

GIT_BRANCH=${GIT_BRANCH:=master}
OPT_NO_GIT_CHECKOUT=""

WORK_VERSION="1"
WORK_VERSION_BUILD="1"
OPT_RPM_VERSION="1"
OPT_RPM_VERSION_BUILD="1"
OPT_RPM_BUILD_NUMBER="0"

OPT_RPM_VERSION_BUILD_FILE=${SRC_DIR_BUILD_ROOT}/var/RPM_VERSION_BUILD
OPT_RPM_BUILD_NUMBER_FILE=${SRC_DIR_BUILD_ROOT}/var/RPM_BUILD_NUMBER

#OS_MAJOR_VERSION=$(lsb_release -s -r | cut -d '.' -f 1)
OS_MAJOR_VERSION=8

OPT_HELP="";

options_vault="$@"

options=`getopt -o hcw:b:v:e:d: --long help,no-checkout,workspace:,branch:,rpm-version:,rpm-version-build:,rpm-build: \
    -n ${program} -- "$@"`

eval set -- "$options"

while true ; do
    case $1 in
	-h|--help) OPT_HELP="1" ; shift ;;
	-c|--no-checkout) OPT_NO_GIT_CHECKOUT="1" ; shift ;;
	-w|--workspace) WORK_DIR_ROOT="$2" ; shift 2 ;;
	-b|--branch) GIT_BRANCH="$2" ; shift 2 ;;
	-v|--rpm-version) OPT_RPM_VERSION="$2" ; shift 2 ;;
	-e|--rpm-version-build) OPT_RPM_VERSION_BUILD="$2" ; shift 2 ;;
	-d|--rpm-build) OPT_RPM_BUILD_NUMBER="$2" ; shift 2 ;;

	--) shift; break;;
	-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
	*) break;;
    esac
done

if [ ! -z "$OPT_HELP" ]; then
    echo "Usage: ${program} [options]" >&2
    echo -e "\t-c | --no-checkout          - do not git checkout" >&2
    echo -e "\t-w | --workspace            - workspace directory" >&2
    echo -e "\t-b | --branch               - git branch to checkout (default: master)" >&2
    echo -e "\t-v | --rpm-version          - rpm version (default: auto)" >&2
    echo -e "\t-e | --rpm-version-build    - rpm build version (default: auto)" >&2
    echo -e "\t-d | --rpm-build            - rpm build number (default: auto)" >&2
    exit 1
fi

if [ ! -d "$WORK_DIR_ROOT" ]; then
	echo "Invalid workspace directory: $WORK_DIR_ROOT!" >&2
	exit 1
fi

SELF_CRC=""
SELF_EXE="$0"

CMD_WHEREIS="which --skip-alias"
CMD_CHKSUM=$($CMD_WHEREIS md5sum)

if [ ! -x "$CMD_CHKSUM" ]; then
    CMD_CHKSUM=$($CMD_WHEREIS openssl)
    if [ -x "$CMD_CHKSUM" ]; then
	CMD_CHKSUM+=" md5"
    fi
fi

if [ ! -z "$CMD_CHKSUM" ]; then
    if [ -x "$CMD_CHKSUM" ]; then
	SELF_CRC=$($CMD_CHKSUM $SELF_EXE)
    else
	unset CMD_CHKSUM
    fi
fi

if [[ "$GIT_BRANCH" == *"origin"* ]] || [[ "$GIT_BRANCH" == *"remotes"* ]]; then
	GIT_CHECKOUT_BRANCH=$GIT_BRANCH
    else
	echo "Setting branch as remotes/origin/${GIT_BRANCH}" >&2
	GIT_CHECKOUT_BRANCH="remotes/origin/${GIT_BRANCH}"
fi

if [ -z "$OPT_NO_GIT_CHECKOUT" ]
then
    echo -n "Fetching git changes:" >&2
    CMD_GIT_PULL_RESULT=$(cd $SRC_DIR_ROOT && (git fetch --all --force --prune 2>&1))

    if [ "$?" -ne 0 ]
    then
	echo "git pull error!" >&2
	echo $CMD_GIT_PULL_RESULT >&2
	exit 1
    else
	echo "ok" >&2
    fi

    echo -n "Cleaning git tree:" >&2
    CMD_GIT_CLEAN_RESULT=$(cd $SRC_DIR_ROOT && (git clean -f -d ; git clean -X -f 2>&1))

    if [ "$?" -ne 0 ]
    then
	echo "git clean error!" >&2
	echo $CMD_GIT_CLEAN_RESULT >&2
	exit 1
    else
	echo "ok" >&2
    fi

    echo -n "git checkout branch ${GIT_CHECKOUT_BRANCH}:" >&2
    CMD_GIT_CHECKOUT_RESULT=$(cd $SRC_DIR_ROOT && (git checkout --force "${GIT_BRANCH}" ; git reset --hard "${GIT_CHECKOUT_BRANCH}" 2>&1))

    if [ "$?" -ne 0 ]
    then
	echo "git checkout ${GIT_BRANCH} error!" >&2
	echo $CMD_GIT_CHECKOUT_RESULT >&2
	exit 1
    else
	echo "ok" >&2

	CMD_GIT_CURRENT_BRANCH_RESULT=$(cd $SRC_DIR_ROOT && (git rev-parse --abbrev-ref HEAD 2>&1))
	if [ "$?" -ne 0 ]
	then
	    echo "Cannot get the current branch name!" >&2
	    echo $CMD_GIT_CURRENT_BRANCH_RESULT >&2
	    exit 1
	fi

	if [ "$GIT_BRANCH" != "$CMD_GIT_CURRENT_BRANCH_RESULT" ]; then
	    echo "Current working branch \"$CMD_GIT_CURRENT_BRANCH_RESULT\" differs from the requested \"$GIT_BRANCH\" branch" >&2
	    exit 1
	fi

	if [ -z "$CMD_CHKSUM" ]; then
	    echo "Can't check build script updates." >&2
	else
	    SELF_NEW_CRC=$($CMD_CHKSUM $SELF_EXE)

	    if [ "$SELF_CRC" != "$SELF_NEW_CRC" ]; then
		echo "Build script updated. Respawning into the new script..." >&2
		EXEC_OPTIONS="${options_vault} --no-checkout"
		exec ${SHELL} $SELF_EXE $EXEC_OPTIONS
	    fi
	fi

    fi
fi


if [ -f "$OPT_RPM_BUILD_NUMBER_FILE" ]; then
    OPT_RPM_BUILD_NUMBER=$(cat "$OPT_RPM_BUILD_NUMBER_FILE")
fi

let "OPT_RPM_BUILD_NUMBER++"
echo $OPT_RPM_BUILD_NUMBER > $OPT_RPM_BUILD_NUMBER_FILE

BUILD_ARCH=x86_64

WORK_VERSION_BUILD="$OPT_RPM_VERSION_BUILD"

RPM_BUILD_NUMBER="$OPT_RPM_BUILD_NUMBER"

SRC_PACKAGE=pbxm-perl-lib-${WORK_VERSION}.${WORK_VERSION_BUILD}

RPM_SPEC_FILE=pbxm-perl-lib.spec
RPM_NAME=${SRC_PACKAGE}-${RPM_BUILD_NUMBER}.el${OS_MAJOR_VERSION}
RPM_FILE=${RPM_NAME}.${BUILD_ARCH}
RPM_FILE_NAME=${RPM_FILE}.rpm
RPM_SRC_FILE_NAME=${RPM_NAME}.src.rpm
RPM_BUILD_ROOT_NAME=rpmbuild
RPM_BUILD_DIR=${SRC_DIR_BUILD_ROOT}/${RPM_BUILD_ROOT_NAME}

SYNC_ROOT=${RPM_BUILD_DIR}/tmp/${SRC_PACKAGE}

if [ ! -f "${SRC_DIR_BUILD_ROOT}/pkg/rpm/SPECS/${RPM_SPEC_FILE}" ]
then
    echo "File ${RPM_SPEC_FILE} not found!" >&2
    exit 1
fi

echo -n "Building \"${RPM_FILE}\":" >&2

rm -rf ${RPM_BUILD_DIR}

mkdir -p ${RPM_BUILD_DIR}/{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp}
mkdir -p ${SYNC_ROOT}

rsync -l -p -E -r --acls --xattrs --owner --group --times \
--include=.* \
--exclude=build/* \
--exclude=rpmbuild/* \
--exclude=*.pod \
--exclude=.git \
--exclude=.gitignore \
${WORK_DIR_ROOT}/ ${SYNC_ROOT}

TAR_RESULT=$(tar --create --gzip --file ${RPM_BUILD_DIR}/tmp/${SRC_PACKAGE}.tar.gz --directory ${RPM_BUILD_DIR}/tmp --verbose --exclude=build --exclude=rpmbuild ${SRC_PACKAGE} 2>&1)

if [ ! -f "${RPM_BUILD_DIR}/tmp/${SRC_PACKAGE}.tar.gz" ]
then
    echo "File ${RPM_BUILD_DIR}/tmp/${SRC_PACKAGE}.tar.gz not found. Error while archiving module" >&2
    exit 1
fi

cp -f ${RPM_BUILD_DIR}/tmp/${SRC_PACKAGE}.tar.gz ${RPM_BUILD_DIR}/SOURCES/${SRC_PACKAGE}.tar.gz

if [ ! -f "${RPM_BUILD_DIR}/SOURCES/${SRC_PACKAGE}.tar.gz" ]
then
    echo "File ${RPM_BUILD_DIR}/SOURCES/${SRC_PACKAGE}.tar.gz not found. Error while copying module archive" >&2
    exit 1
fi

if [ -d "${RPM_BUILD_DIR}/tmp" ]; then
    rm -rf ${RPM_BUILD_DIR}/tmp/*
fi

cp -f ${SRC_DIR_BUILD_ROOT}/pkg/rpm/SPECS/${RPM_SPEC_FILE} ${RPM_BUILD_DIR}/SPECS/${RPM_SPEC_FILE}

if [ ! -f "${RPM_BUILD_DIR}/SPECS/${RPM_SPEC_FILE}" ]
then
    echo "File ${RPM_BUILD_DIR}/SPECS/${RPM_SPEC_FILE} not found. Error while copying SPEC file" >&2
    exit 1
fi

RPM_BUILD_RESULT=$(RPM_BUILD_DIR=${RPM_BUILD_DIR} OS_MAJOR_VERSION=${OS_MAJOR_VERSION} MODULE_VERSION="${WORK_VERSION}.${WORK_VERSION_BUILD}" MODULE_VERSION_BUILD=${RPM_BUILD_NUMBER} rpmbuild --define '__topdir ${RPM_BUILD_DIR}' -ba ${RPM_BUILD_DIR}/SPECS/${RPM_SPEC_FILE} 2>&1)

if [ ! -f "${RPM_BUILD_DIR}/RPMS/${BUILD_ARCH}/${RPM_FILE_NAME}" ]
then
    echo "File ${RPM_BUILD_DIR}/RPMS/${BUILD_ARCH}/${RPM_FILE_NAME} not found. Error while building RPM." >&2
    echo ${RPM_BUILD_RESULT}
    exit 1
fi

if [ ! -d "$SRC_DIR_OUTPUT" ]; then
    mkdir -p $SRC_DIR_OUTPUT
fi

mv -f ${RPM_BUILD_DIR}/RPMS/${BUILD_ARCH}/${RPM_FILE_NAME} ${SRC_DIR_OUTPUT}/${RPM_FILE_NAME}

mv -f ${RPM_BUILD_DIR}/SRPMS/${RPM_SRC_FILE_NAME} ${SRC_DIR_OUTPUT}/${RPM_SRC_FILE_NAME}


if [ ! -f "${SRC_DIR_OUTPUT}/${RPM_FILE_NAME}" ]
then
    echo "File ${SRC_DIR_OUTPUT}/${RPM_FILE_NAME} not found. Error while copying RPM." >&2
    exit 1
fi

rm -rf ${RPM_BUILD_DIR}

echo "ok" >&2

if [ -f "$OPT_RPM_BUILD_NUMBER_FILE" ]; then
    echo -n "Updating git build number:" >&2

    CMD_GIT_PUSH_RESULT=$(cd $SRC_DIR_ROOT && (git add $OPT_RPM_BUILD_NUMBER_FILE && git commit -m 'build number autoupdate' && git push 2>&1))

    if [ "$?" -ne 0 ]
    then
	echo "git push error!" >&2
	echo $CMD_GIT_PUSH_RESULT >&2
	exit 1
    else
	echo "ok" >&2
    fi

fi

echo "RPM: ${SRC_DIR_OUTPUT}/${RPM_FILE_NAME}"

exit 0
