#!/bin/bash

#set -x

debug=0

trapexit () {
[ -n "$1" ] && echo "exit detected $1"
((debug)) || git checkout -f "$mainbranch"
rm -fr *.res
[ -n "$1" ] && exit 10
exit 0
}
trap "trapexit SIGINT"  SIGINT
trap "trapexit SIGTERM" SIGTERM
trap "trapexit"         SIGQUIT


#wd="${0%${0##*/}}"; [ -z "$wd" ] && wd="$PWD"
wd="$PWD"

fileconf="/etc/git-task.conf"

servers="localhost"
quenchdir="geartask.d"
name="$(echo "$wd" | sed "s/\/$//;s/.*\///")"
mainbranch="master"
cacherepos="/var/lib/gitalt-tasker/repos"
branch="sisyphus"
connect=
specbranchforce="specs"
suffixes=

lines="$(sed -n "$=" "$fileconf")"
for((line=1;line<=lines;line++)); do
    str="$(sed "$line"'!d;s/^#.*//;s/[[:space:]]#.*//;s/^[[:space:]]\+//;s/[[:space:]]\+$//;' "$fileconf")"
    [ -z "$str" ] && continue
    case "$str" in
        quenchdir=*) eval "${str}" ;;
        name=*) eval "${str}" ;;
        mainbranch=*) eval "${str}" ;;
        cacherepos=*) eval "${str}" ;;
        branch=*) eval "${str}" ;;
        connect=*) eval "${str}" ;;
        specbranchforce=*) eval "${str}" ;;
        servers=*) ;;
        \[Suffixes\])
            ((line++))
            end="$(sed -n "$line,$"'!d;s/[[:space:]]*#.*//;s/[[:space:]]\+//g;s/\[.*\]/&/;ta;bb;:a;=;:b;' "$fileconf")"
            [ -z "$end" ] && (( end=$(sed -n "$=" "$fileconf")+1 ))
            ((end--))
            suffixes=" $(sed -e  "$line,$end"'!d;s/^#.*//;s/[[:space:]]#.*//;s/[[:space:]]\+//g;' "$fileconf" | sed 'N;s/\n/ /g;') "
            ((line=end))
            ;;
        \[Skiprepo\])
            ((line++))
            end="$(sed -n "$line,$"'!d;s/[[:space:]]*#.*//;s/[[:space:]]\+//g;s/\[.*\]/&/;ta;bb;:a;=;:b;' "$fileconf")"
            [ -z "$end" ] && (( end=$(sed -n "$=" "$fileconf")+1 ))
            ((end--))
            Skiprepo=" $(sed -e  "$line,$end"'!d;s/^#.*//;s/[[:space:]]#.*//;s/[[:space:]]\+//g;' "$fileconf" | sed 'N;s/\n/ /g;') "
            ((line=end))
            ;;
        *) echo "${0##*/}: $fileconf:$line: $str: syntax error or unknown option"; exit 1 ;;
    esac
done


#wd="${0%${0##*/}}"; [ -z "$wd" ] && wd="$PWD"
wd="$PWD"

release=
version=
build=
branch_release_num=

for opt in $*; do
    case "$opt" in
    --repo=*) branch="${opt#*=}";;
    --all) branch=;;
    --version) echo "${0##*/}, version 0.0.1.13-alt1.6"; exit 0;;
    --help) 
cat <<EOF
${0##*/} [options] [[version] release]

Options:
    --all                   - send to all repositories
    --repo="repo repo1 ..." - send to selected repositories
    --version               - program version
    --help                  - this text

EOF
        exit 0; ;;
    *)
        if [ -z "$release" ]; then release="$opt"; continue; fi
        if [ -z "$version" ]; then 
            version="$release"
            release="$opt"
            continue; 
        fi
    ;;
    esac
done



((debug)) || git checkout -f "$mainbranch"

if ! [ -d "$wd/$name" ]; then echo "${0##*/}: $wd/$name is no directory or not found"; exit 2; fi
# [ -f "$counter" ] || exit 2
[ -f "$wd/$name.spec" ] || exit 2

value=$(sed '/Version/!d;s/^[[:space:]]*Version[[:space:]]*:[[:space:]]\+//;s/^[[:space:]]\+//;s/[[:space:]]\+$//;' "$wd/$name.spec")
[ -z "$version" ] && version="$value"
if [ "$version" != "$value" ]; then
    [ -z "$release" ] && release="alt1"
    build=0
    branch_release_num=0
else
    value=$(sed '/Release/!d;s/^[[:space:]]*Release[[:space:]]*:[[:space:]]\+//;s/^[[:space:]]\+//;s/[[:space:]]\+$//;s/%branch_release[[:space:]]\+//' "$wd/$name.spec")
    build="$(echo "$value" | sed "s/.*\.//")"
    value="$(echo "$value" | sed "s/\..*//")"
    if [ "$value" == "$build" ]; then build=0; branch_release_num=0; fi
    [ -z "$release" ] && release="$value"
    if [ -z "$release" ]; then release="alt1"; build=0; branch_release_num=0; fi
    if [ "$release" != "$value" ]; then build=0; branch_release_num=0; fi
fi

    value="$(echo "$build" | sed "s/[[:digit:]]\+$//g")"
    [ -n "$value" ] && echo "${0##*/}: WARNING: the build <$build> is contains a bad character"
    build="${build#$value}"
    [ -z "$branch" ] && (( ++build ))
    (( 0==build )) && (( ++build ))
    build="$value$build"

if [ -z "$version" ]; then
    echo "${0##*/}: FATAL: version 0.0.1.13-alt1.6"
    exit 1;
fi

if [ ${release:0:3} != "alt" ]; then
    echo "${0##*/}: FATAL: release is not contains \"alt*\""
    exit 2;
fi

(( 0==branch_release_num )) && branch_release_num=1

sed -i "s/Version:.*/Version: $version/" "$wd/$name.spec"
sed -i "s/Release:.*/Release: %branch_release $release.$build/" "$wd/$name.spec"
if ! egrep -q "[[:space:]]*%define[[:space:]]+branch_release_num[[:space:]]+" "$wd/$name.spec"; then
     sed -i "1s/^/%define branch_release_num 1\n/;" "$wd/$name.spec";
fi

cp -fr "$wd/$name"{,.res} || exit 2
# touch "$counter" "$wd/$name.spec"
# cp -f "$counter"{,.res} || exit 2
cp -f "$wd/$name.spec"{,.res} || exit 2
# ((debug)) || git add "$counter"
((debug)) || git add "$name.spec"
#((debug)) || git commit -am "Autosave count $version-$release.$build"

repos="$(eval "$connect ssh git.alt task new --help 2>&1" | sed '/alid repositories/!d;s/.*://;')"
if [ -n "$repos" ]; then
    echo "$repos" >"$cacherepos"
else
    repos="$(cat "$cacherepos")"
fi
#repos="500 5001 5002"
echo "$repos" | grep -q "sisyphus" || repos="sisyphus $repos"
branches=
error=0
[ -z "$branch" ] && branch="$repos"
if [ -n "$repos" ]; then
    for br in $branch; do
        if echo "$repos" | grep -q $br; then
            branches="$branches $br"
        else
            echo "WARNING! branch $br is not valid branch. Branch $br has been skip"
            error=1
        fi 
    done
fi
((error)) && echo "Valid branchs is $repos"

task=
filetask=
order=1
rnd="$(date +%Y-%m-%d-%H-%M-%S-%N)"
tasktime="$(date +%s.%N)"
for repo in $branches; do
    echo "$Skiprepo" | grep -q " $repo " && continue;
    srepo="$(echo "$suffixes" | sed "/^$repo=/"'!d;s/.*=//')"
    if [ -z "$srepo" ]; then
        srepo="$repo"
        srepo="$(echo "$srepo" | sed "s/\.//g;s/[[:alpha:]]//g")"
        [ -n "$srepo" ] && srepo="M$srepo"
    fi
    tag="$version-$release.$build"
    [ -n "$srepo" ] && tag="$version-$(rpm --define "branch_release_num \"$branch_release_num\"" --define "branch_switch \"$srepo\"" --eval "%branch_release $release.$build")"
    reponame="$srepo"
    [ -z "$reponame" ] && reponame="$repo"
    [ -n "$specbranchforce" ] && reponame="$specbranchforce"
#    exit
    ((debug)) || if git checkout -fb "$reponame"; then
        git pull -f . "$mainbranch" 2>&1 >/dev/null
#        git rm -r --cached --ignore-unmatch --quiet *
#        cp -f "$counter"{.res,}
        cp -f "$wd/$name.spec"{.res,}
#        git add "$counter"
        git add "$name.spec"
        git commit -am "Init autocomit"
        eval "$connect git remote update"
    else git checkout -f "$reponame"; fi
    ((debug)) || git pull --commit -f . "$mainbranch"
#    cp -f "$counter"{.res,}
    cp -f "$wd/$name.spec"{.res,}
    sed -i "s/Version:.*/Version: $version/" "$wd/$name.spec"
    sed -i "s/Release:.*/Release: %branch_release $release.$build/" "$wd/$name.spec"
#    sed -i "s/%define[[:space:]]\+branch_switch[[:space:]]\+.*/%define branch_switch \"$srepo\"/" "$wd/$name.spec"
    sed -i "s/%define[[:space:]]\+branch_switch[[:space:]]\+.*/%define branch_switch $srepo/" "$wd/$name.spec"
    sed -i "s/[[:space:]]*%define[[:space:]]\+branch_release_num[[:space:]]\+.*/%define branch_release_num $branch_release_num/" "$wd/$name.spec"
    if git tag | grep -q "${tag%.*}"; then
        brn="$(git tag | grep "${tag%.*}" | sort -r | sed '1!d;s/.*\.//')"
        if [ -n "$srepo" ]; then
            ((brn++));
            sed -i "s/[[:space:]]*%define[[:space:]]\+branch_release_num[[:space:]]\+.*/%define branch_release_num $brn/" "$wd/$name.spec"
        fi
        branch_release_num="$brn"
    [ -n "$srepo" ] && tag="$version-$(rpm --define "branch_release_num \"$branch_release_num\"" --define "branch_switch \"$srepo\"" --eval "%branch_release $release.$build")"
    fi
    add_changelog -e "- Autocommit for branch $repo" "$wd/$name.spec" 2>&1 >/dev/null
#     line="$(grep -n "$tag" "$wd/$name.spec")"
#     line="${line%%:*}"
#     if [ -z "$line" ]; then echo "FATAL: cant find changelog for $tag"; exit 1; fi
#     ((line++))
    
    echo "Sending tag $tag into repo $repo"
    ((debug)) || git commit -am "Autocommit for build #$tag"
    ((debug)) || if ! git tag -f -s -m "$tag" "$tag"; then continue; fi
#exit
    ((debug)) || eval "$connect git push origin $reponame"
    ((debug)) || eval "$connect git push origin --tags"

    order="0000$order"
    order="${order:${#order}-3}"
    filetask="$(echo "$order-$name-$tag.$rnd" | sed "s|/||g")"
    ((debug)) || echo "cmd:" ssh git.alt build -b "$repo" "packages/$name.git" "$tag" >"/tmp/$filetask";
    echo "task: " >>"/tmp/$filetask";
    echo "name: $name" >>"/tmp/$filetask";
    echo "time: $tasktime" >>"/tmp/$filetask";
    for server in $servers; do
        echo "Try to send on a server $server"
        if [ "$server" == "localhost" ]; then
            rsync "/tmp/$filetask" "$HOME/$quenchdir/" && break;
        else
            rsync "/tmp/$filetask" "$server":"$HOME/$quenchdir/" && break;
        fi
    done
    rm -f "/tmp/$filetask"
    [ -f "/tmp/$filetask" ] && rm -f "/tmp/$filetask"
    order="$(echo "$order" | sed "s/^0*//g")"
    ((order++))

done

trapexit
exit
