#!/usr/bin/bash

# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide.
# This software is distributed without any warranty.

# You should have received a copy of the CC0 Public Domain Dedication
# along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

REPOCTL_FUNCTIONS='/usr/share/repoctl/functions'
[ -f /etc/repoctl_functions ] && REPOCTL_FUNCTIONS=$(cat /etc/repoctl_functions)
. $REPOCTL_FUNCTIONS

function usage_cmd()
{
    case "$1" in
	mvpkg)
	    cat <<EOF
Usage: repoctl mvpkg [options] --srcrepo distribution/section/sectionrepo \\
			       --dstrepo distribution/section/sectionrepo \\
			       --srcpkg|--binpkg name

Options:
  --dry-run : don't do anything, but show what would have been done.
  --no-genhdlists : don't regenerate hdlists
  --srcpkg name : name of a source package. All the binary packages
                   generated by this source package will also be moved.
  --binpkg name : name of a binary package.

Example :
  Move emacs packages from 1/core/updates_testing to 1/core/updates :
  repoctl mvpkg --srcrepo 1/core/updates_testing --dstrepo 1/core/updates \
                  --srcpkg emacs
EOF
	    ;;
	rmpkg)
	    cat <<EOF
Usage: repoctl rmpkg [options] --srcrepo distribution/section/sectionrepo \\
			       --srcpkg|--binpkg name

Options:
  rmpkg can take the same options as mvpkg. See repoctl mvpkg --help
  for details.

Example :
  Remove emacs package from 1/core/updates_testing repository :
  repoctl rmpkg --srcrepo 1/core/updates_testing --srcpkg emacs

EOF
	    ;;
	lspkg)
	    cat <<EOF
Usage: repoctl lspkg --srcrepo distribution/section/sectionrepo \\
		     --srcpkg|--binpkg name

Example :
  List emacs packages from 1/core/updates_testing repository :
  repoctl lspkg --srcrepo 1/core/updates_testing --srcpkg emacs
EOF
	    ;;
	repolock)
	    cat <<EOF
Usage: getrepolock|rmrepolock --srcrepo distribution/section/sectionrepo

Get or release lock on a repository.

Warning: one process should not try to get a lock on more than one
repository at the same time. It is however possible to lock all
repositories of a distribution using getdistrolock/rmdistrolock.

EOF
	;;
	genhdlists)
	   cat <<EOF
Usage: genhdlists [--needed] [--srcrepo distribution/section/sectionrepo]

Options:
  --srcrepo : rebuild hdilsts from selected repository
  --needed  : rebuild hdlists for all repositories that have been updated
              without hdlists rebuild.

EOF
	;;
        mirrordistro)
	   cat <<EOF
Usage: mirrordistro distrorelease

Mirror the distribution tree to the main mirror.
EOF
       ;;
	
    esac
}

function mvpkg()
{
    args=$(getopt -o hn -l srcrepo:,dstrepo:,dry-run,remove,help,no-genhdlists,no-mirror,srcpkg:,binpkg: -- "$@")
    [ $? -ne 0 ] && usage_cmd mvpkg && exit 1
    eval set -- "$args"
    [ $# -lt 1 ] && exit 1
    while [ $# -gt 0 ]
    do
	case $1 in
	    -h|--help)
		if [ -z "$remove" ]
		then
		    usage_cmd mvpkg
		else
		    usage_cmd rmpkg
		fi
		exit 0
		;;
	    -n|--dry-run)
		dryrun=echo
		shift;;
	    --remove)
		remove=1
		shift;;
	    --no-genhdlists)
		nogenhdlists=1
		shift;;
	    --no-mirror)
		nomirror=1
		shift;;
	    --srcrepo)
		IFS='/' read -ra srcrepo <<< "$2"
		shift;shift;;
	    --dstrepo)
		IFS='/' read -ra dstrepo <<< "$2"
		shift;shift;;
	    --srcpkg)
		srcpkg="$2"
		shift;shift;;
	    --binpkg)
		binpkg="$2"
		shift;shift;;
	    --)
		shift;break;;
	    -*)
		usage
		exit 1
		;;
	    *)
		break
		;;
	esac
    done
    if [ -z "$srcrepo" -o -z "$remove$dstrepo" -o \( -z "$srcpkg" -a -z "$binpkg" \) ]
    then
	usage
	exit 1
    fi
    if [ -n "$srcpkg" ]
    then
	move_pkg "${srcrepo[0]}" "${srcrepo[1]}" "${srcrepo[2]}" \
	         "${dstrepo[0]}" "${dstrepo[1]}" "${dstrepo[2]}" \
		 "$srcpkg" "/dev/stdout"
	if [ -z "$nogenhdlists" ]
	then
	    update_hdlists "${srcrepo[0]}" "${srcrepo[1]}" "${srcrepo[2]}"
	    [ -n "$dstrepo" ] &&
		update_hdlists "${dstrepo[0]}" "${dstrepo[1]}" "${dstrepo[2]}"
	    if [ -z "$nomirror" ]
	    then
		mirror_repository "${srcrepo[0]}"
		[ -n "${dstrepo[0]}" ] && [ "${srcrepo[0]}" != "${dstrepo[0]}" ] &&
		    mirror_repository "${dstrepo[0]}"
	    fi
	fi
    else
	echo "The --binpkg option is not supported yet"
    fi
}

function rmpkg()
{
    mvpkg --remove $@
}

function lspkg()
{
    args=$(getopt -o hn -l srcrepo:,help,srcpkg:,binpkg: -- "$@")
    [ $? -ne 0 ] && usage_cmd mvpkg && exit 1
    eval set -- "$args"
    [ $# -lt 1 ] && exit 1
    while [ $# -gt 0 ]
    do
	case $1 in
	    -h|--help)
		usage_cmd lspkg
		exit 0
		;;
	    --srcrepo)
		IFS='/' read -ra srcrepo <<< "$2"
		shift;shift;;
	    --srcpkg)
		srcpkg="$2"
		shift;shift;;
	    --binpkg)
		binpkg="$2"
		shift;shift;;
	    --)
		shift;break;;
	    -*)
		usage
		exit 1
		;;
	    *)
		break
		;;
	esac
    done
    if [ -z "$srcrepo" -o -z "$srcpkg$binpkg" ]
    then
	usage
	exit 1
    fi
    if [ -n "$srcpkg" ]
    then
	ls_pkg "${srcrepo[0]}" "${srcrepo[1]}" "${srcrepo[2]}" "$srcpkg" "/dev/stdout"
    else
	echo "The --binpkg option is not supported yet"
    fi

}

function repolock()
{
    args=$(getopt -o h -l srcrepo:,help,get,rm -- "$@")
    [ $? -ne 0 ] && usage_cmd repolock && exit 1
    eval set -- "$args"
    [ $# -lt 1 ] && exit 1
    while [ $# -gt 0 ]
    do
	case $1 in
	    -h|--help)
		usage_cmd repolock
		exit 0
		;;
	    --srcrepo)
		IFS='/' read -ra srcrepo <<< "$2"
		shift;shift;;
	    --get)
		command=get_repo_lock
		shift;;
	    --rm)
		command=rm_repo_lock
		shift;;
	    --)
		shift;break;;
	    -*)
		usage
		exit 1
		;;
	    *)
		break
		;;
	esac
    done
    if [ -z "$srcrepo" ]
    then
	usage_cmd repolock
	exit 1
    fi
    $command "${srcrepo[0]}" "${srcrepo[1]}" "${srcrepo[2]}"
}

function genhdlists()
{
    args=$(getopt -o h -l srcrepo:,help,needed -- "$@")
    [ $? -ne 0 ] && usage_cmd genhdlists && exit 1
    eval set -- "$args"
    [ $# -lt 1 ] && exit 1
    while [ $# -gt 0 ]
    do
	case $1 in
	    -h|--help)
		usage_cmd genhdlists
		exit 0
		;;
	    --srcrepo)
		IFS='/' read -ra srcrepo <<< "$2"
		shift;shift;;
	    --needed)
		local needed=1
		shift;;
	    --)
		shift;break;;
	    -*)
		usage
		exit 1
		;;
	    *)
		break
		;;
	esac
    done
    if [ -z "$srcrepo$needed" ]
    then
	usage_cmd genhdlists
	exit 1
    fi
    if [ -n "$srcrepo" ]
    then
	update_hdlists "${srcrepo[0]}" "${srcrepo[1]}" "${srcrepo[2]}"
    fi
    if [ -n "$needed" ]
    then
	update_hdlists_if_needed
    fi
}

function mirrordistro()
{
    if [ $# != 1 ]
    then
	usage_cmd mirrordistro
	exit 1
    fi
    if [ "$1" = "--help" ]
    then
	usage_cmd mirrordistro
    else
	mirror_repository "$1"
    fi
}

function usage()
{
    cat <<EOF
  Usage: repoctl COMMAND [COMMAND ARGUMENTS]

  Useful commands :
     mvpkg
     lnpkg
     rmpkg
     lspkg
     genhdlists
     mirrordistro
     getrepolock
     rmrepolock
     getdistrolock
     rmdistrolock

  For more infos about a command, use :
    repoctl COMMAND --help

EOF
}

case "$1" in
    mvpkg)
	shift
	mvpkg $@
	;;
    rmpkg)
	shift
	rmpkg $@
	;;
    lspkg)
	shift
	lspkg $@
	;;
    getrepolock)
	shift
	repolock --get $@
	;;
    rmrepolock)
	shift
	repolock --rm $@
	;;
    genhdlists)
	shift
	genhdlists $@
	;;
    mirrordistro)
	shift
	mirrordistro $@
	;;
    *)
	usage
	exit 1
	;;
esac

