#!/usr/bin/sh

set -e

LOCALDIR="$(dirname $0)"
if [ -d "$LOCALDIR/.git" -a -f "$LOCALDIR/functions" ]; then
  . "$LOCALDIR/functions"
else
  . /usr/share/mgatools/functions
fi

sync=
if [ "$1" = "--sync" ]; then
    sync=yes
    shift
fi

noconfirm=
if [ "$1" = "--no-confirm" ]; then
    noconfirm=yes
    shift
fi

function usage()
{
    echo "Usage: $(basename $0) [--dry-run] [--sync] [--no-confirm] [--backport] <release>/<section>/<pkg> [[--backport] <release>/<section>/<pkg>...]" >&2
    exit 1
}
[ $# -lt 1 ] && usage

declare -a _releases;
declare -a _sections;
declare -a _srcsubsections;
declare -a _destsubsections;
declare -a _pkgs;
declare -a _pkgfiles;
declare -a _oldpkgfiles;

# Assume the input is the full srpm name (used to avoid validation)
declare _fullsrpmname="y"

function parse_args()
{
    local -a tmptriplet;
    local subsection;
    local -i i=0;

    while [ $# -gt 0 ]; do
        subsection='updates';
        if [ "$1" = "--backport" ]; then
            subsection='backports';
            shift
        fi

        OIFS="$IFS"; IFS=/; tmptriplet=($1); IFS="$OIFS";

        [ ${#tmptriplet[*]} -ne 3 ] && usage

        _releases[$i]=${tmptriplet[0]}
        _sections[$i]=${tmptriplet[1]}
        _pkgs[$i]=${tmptriplet[2]}

        valid_release ${_releases[$i]}
        valid_section ${_sections[$i]}

        _srcsubsections[$i]="${subsection}_testing"
        _destsubsections[$i]=$subsection

        # Special case in cauldron where we move updates_testing -> release
        if [ 'cauldron' = "${_releases[$i]}" ]; then
            if [ 'backports' = "$subsection" ]; then
                echo "Error: Cannot use --backport with cauldron" >&2
                exit 1
            fi
            _destsubsections[$i]="release"
        fi
        ((++i))
        shift
    done
}
parse_args "$@"

function find_srpms()
{
    local file
    local pkg
    local bfile
    local exactsrpm

    for ((i=0;i<${#_releases[*]};++i)); do
        exactsrpm=
        for file in "$distribdir/${_releases[$i]}/SRPMS/${_sections[$i]}/${_srcsubsections[$i]}/"*.rpm; do
            pkg=$(rpm -qp --qf '%{NAME}' "$file")

            # Check exact match
            bfile=$(basename "$file")
            if [ "$bfile" = "${_pkgs[$i]}" ]; then
                exactsrpm=y
                _pkgs[$i]=$pkg
                _pkgfiles[$i]=$bfile
                break
            fi

            # Check for src package name
            if [ "$pkg" = "${_pkgs[$i]}" ]; then
                _pkgfiles[$i]=$bfile
                break
            fi
        done

        # If we didn't find an exact srpm, then update our global var accordingly
        [ -z "$exactsrpm" ] && _fullsrpmname=

        if [ -z "${_pkgfiles[$i]}" ]; then
            echo "The package '${_pkgs[$i]}' could not be found in the '${_releases[$i]}/${_sections[$i]}/${_srcsubsections[$i]}' repository." >&2
            exit 2
        fi

        _oldpkgfiles[$i]=
        if [ 'release' = "${_destsubsections[$i]}" ]; then
            # In cauldron we also have to move the old version from release to ~schedbot/old/
            # We know srcname is a %{name} now.
            for file in "$distribdir/${_releases[$i]}/SRPMS/${_sections[$i]}/release/${_pkgs[$i]}-"*.rpm; do
                pkg=$(rpm -qp --qf '%{NAME}' "$file")
                if [ "$pkg" = "${_pkgs[$i]}" ]; then
                     bfile=$(basename "$file")
                     _oldpkgfiles[$i]=$bfile
                     break
                fi
            done

            # (cg) Is this a valid check? What if it's a new package introduced first into testing
            # Ultimately this is not very likely, so ignore it for now.
            if [ -z "${_oldpkgfiles[$i]}" ]; then
                echo "The package '${_pkgs[$i]}' could not be found in the '${_releases[$i]}/${_sections[$i]}/${_srcsubsections[$i]}' repository." >&2
                exit 2
            fi
        fi
    done
}
find_srpms

# Safety check
function sanity_check()
{
    local cauldronmsg

    if [ -n "$noconfirm" ]; then
       # We've requested no confirmation. This is only valid when the user
       # supplies a full SRPM name for every package.
       [ "$_fullsrpmname" = "y" ] && return 0
       echo "Sorry, but you requested --no-confirm, but did not give me full SRPM names." >&1
       exit 1
    fi

    echo "The following SRPMs (and their corresponding binaries) will be moved:"
    for ((i=0;i<${#_releases[*]};++i)); do
        echo "- ${_pkgfiles[$i]}"
        if [ 'release' = "${_destsubsections[$i]}" -a -n "${_oldpkgfiles[$i]}" ]; then
            cauldronmsg="${cauldronmsg}- ${_oldpkgfiles[$i]}\n"
        fi
    done
    echo

    if [ -n "$cauldronmsg" ]; then
        echo "The following SRPMs (and their corresponding binaries) will be moved from 'release' to '\~schedbot/old':"
        echo "$cauldronmsg"
        # The above always ends with a blank line... so no need to echo another
    fi

    read -n 1 -p "Are you sure? [Y/n] " yn
    [ -n "$yn" ] && echo
    [ -z "$yn" -o "Y" = "$yn" ] && yn=y
    [ "y" != "$yn" ] && exit
    return 0
}
sanity_check

declare _mailcontent=$(mktemp)
declare _mailcommands=$(mktemp)

function movepkg()
{
    local srcdir="$1"
    local destdir="$2"
    local srcpkg="$3"
    local file
    local srpm

    for file in $(urpmf --synthesis "${srcdir}/media_info/synthesis.hdlist.cz" --qf '%filename:%sourcerpm' ":$srcpkg$" | cut -d: -f1); do
        echo "    $file" | tee -a "$_mailcontent"
        $dryrun mv -v -f "$srcdir/$file" "$destdir" >>"$_mailcommands" 2>&1
    done
}

function movepkgs()
{
    local arch

    for ((i=0;i<${#_releases[*]};++i)); do
        if [ 'release' = "${_destsubsections[$i]}" -a -n "${_oldpkgfiles[$i]}" ]; then
            echo ""
            echo "Moving binary and source rpms:" | tee -a "$_mailcontent"
            for arch in $arches; do
                echo "- $arch:" | tee -a "$_mailcontent"
                movepkg "$distribdir/${_releases[$i]}/$arch/media/${_sections[$i]}/release" "/var/lib/schedbot/old/" "${_oldpkgfiles[$i]}"
                movepkg "$distribdir/${_releases[$i]}/$arch/media/debug/${_sections[$i]}/release" "/var/lib/schedbot/old/" "${_oldpkgfiles[$i]}"
            done
            echo "- source:" | tee -a "$_mailcontent"
            echo "    ${_oldpkgfiles[$i]}" | tee -a "$_mailcontent"
            echo >> "$_mailcontent"
            echo >> "$_mailcontent"
            $dryrun mv -v -f "$distribdir/${_releases[$i]}/SRPMS/${_sections[$i]}/release/${_oldpkgfiles[$i]}" "/var/lib/schedbot/old/" >>"$_mailcommands" 2>&1
        fi

        echo ""
        echo "Moving binary and source rpms:" | tee -a "$_mailcontent"
        for arch in $arches; do
            echo "- $arch:" | tee -a "$_mailcontent"
            movepkg "$distribdir/${_releases[$i]}/$arch/media/${_sections[$i]}/${_srcsubsections[$i]}" "$distribdir/${_releases[$i]}/$arch/media/${_sections[$i]}/${_destsubsections[$i]}/" "${_pkgfiles[$i]}" "$_mailcontent" "$_mailcommands"
            movepkg "$distribdir/${_releases[$i]}/$arch/media/debug/${_sections[$i]}/${_srcsubsections[$i]}" "$distribdir/${_releases[$i]}/$arch/media/debug/${_sections[$i]}/${_destsubsections[$i]}/" "${_pkgfiles[$i]}" "$_mailcontent" "$_mailcommands"
        done
        echo "- source:" | tee -a "$_mailcontent"
        echo "    ${_pkgfiles[$i]}" | tee -a "$_mailcontent"
        echo >> "$_mailcontent"
        echo >> "$_mailcontent"
        $dryrun mv -v -f "$distribdir/${_releases[$i]}/SRPMS/${_sections[$i]}/${_srcsubsections[$i]}/${_pkgfiles[$i]}" "$distribdir/${_releases[$i]}/SRPMS/${_sections[$i]}/${_destsubsections[$i]}/" >>"$_mailcommands" 2>&1
    done
}
movepkgs

if [ -n "$dryrun" ]; then
    echo
    echo "Raw Commands:"
    cat "$_mailcommands"
else
    if [ -z "$sync" ]; then
        echo >>"$_mailcontent"
        echo "Warning: hdlist update+sync was not performed during this move" >>"$_mailcontent"
        echo >>"$_mailcontent"
        echo >>"$_mailcontent"
    fi

    cat "$_mailcommands" >>"$_mailcontent"
    /usr/bin/mailx -s "$(basename $0): ${#_releases[*]} source package(s) moved" -S "from=$moveupdate_mailfrom" "$moveupdate_mailto" < "$_mailcontent"

    if [ -n "$sync" ]; then
        updated="xxxx"
        for ((i=0;i<${#_releases[*]};++i)); do
            if ! inlist "${_releases[$i]}/${_sections[$i]}/${_srcsubsections[$i]}" "$updated"; then
                update_distro_hdlist "${_releases[$i]}" "${_sections[$i]}" "${_srcsubsections[$i]}"
                updated="$updated ${_releases[$i]}/${_sections[$i]}/${_srcsubsections[$i]}"
            fi
            if ! inlist "${_releases[$i]}/${_sections[$i]}/${_destsubsections[$i]}" "$updated"; then
                update_distro_hdlist "${_releases[$i]}" "${_sections[$i]}" "${_destsubsections[$i]}"
                updated="$updated ${_releases[$i]}/${_sections[$i]}/${_destsubsections[$i]}"
            fi
        done

        updated="xxxx"
        for ((i=0;i<${#_releases[*]};++i)); do
            if ! inlist "${_releases[$i]}" "$updated"; then
                update_common_MD5SUM "${_releases[$i]}"
                mirror_repository "${_releases[$i]}"
                updated="$updated ${_releases[$i]}"
            fi
        done
    fi
fi
rm -f "$_mailcontent" "$_mailcommands"
