#!/bin/sh -e
# $Id: sisyphus_link_src,v 1.3 2005/05/27 14:26:24 legion Exp $

. /etc/sisyphus/functions
. /etc/sisyphus/config

cd "$PREFIX"

export LC_ALL=C LANG=C LANGUAGE=C

verbose=
force_component=
component=contrib
interactive=
action=
tab_char="$(printf \\t)"

Usage() {
    [ "$1" = 0 ] || exec >&2
    cat << EOF
Usage:

$PROG -a [options] <rpm> [<rpm> ...]
$PROG -d [options] <name> [<name> ...]

Options:
    -a, --add             add defined name to index list
    -d, --delete          delete defined name from index list
    -l, --list=LISTNAME   define index list [default: $listname]
    -A                    same as -avi
    -D                    same as -dvi
    -i, --interactive     read 'name' from stdin.
    -v, --verbose         verbose mode
    -h, --help            show this message

EOF
    [ -n "$1" ] && exit "$1" || exit
}

WORKDIR=
exit_handler() {
    local rc=$?
    trap - EXIT
    [ -z "$WORKDIR" ] || rm -rf -- "$WORKDIR"
    exit $rc
}

quote() {
    printf %s "$*" | sed -e 's/[+\`\"$]/\\&/g' || return 1 
}

do_add_package() {
    local rc=0
    local f info n owner owners s src_component
    for f in "$@"; do
	f="${f##*/}"
	src_component="$component"

	[ -f "files/SRPMS/$f" ] || { Info "Error: No such source file: $f"; continue; }

	info="$(rpmquery -p --qf '%{NAME}\t%{CHANGELOGNAME}\n' "files/SRPMS/$f")"
	n="$(printf %s "$info" | cut -f1)"

	if  cut -f1 files/list.src.* | grep -m1 -qsxF "$n" ; then
	    Info "$n already in lists">&2
	    continue
	fi

	[ -z "$verbose" ] || printf '%s ' "$f"
	owner="$(printf %s "$info" | cut -f2 | sed -ne "s,^[^<]*<\\([^@]\\+\\)\\(@\\| at\\).*$,\\1,p")" #"
	[ -n "$owner" ] || { Info "Error: cannot parse owner: $n"; continue; }

	# Kenrel workaround.
	local ktype kmantainers
	if [ "${n#kernel-modules-}" != "$n" ]; then
	    ktype="$(printf %s "$n" | sed -ne 's,^kernel-modules-.*-\([^-]\+-[^-]\+\)$,\1,p')"
	    kmantainers="$(sed -ne "s,^kernel-image-$ktype[[:space:]]\+\(.*\)$,\1,p" files/list.src.kernel)"
	    [ -z "$kmantainers" ] || owner="$owner $kmantainers"
	fi
	[ "${n#kernel-}" = "$n" ] || src_component=kernel
	[ -z "$force_component" ] || src_component="$force_component"

	list="list.src.$src_component"
	[ -f "files/$list" ] || { Info "cannot find list: $(pwd)/$list"; rc=1; continue; }

        printf '%s\t%s\n' "$n" "$owner" >> "$WORKDIR/$list"
	if [ -n "$verbose" ]; then
	    if grep --mmap -m1 -qsxF "${n}${tab_char}${owner}" "$WORKDIR/$list"; then 
		printf 'addition to %s succesed\n' "$list"
		continue
	    fi
	    printf 'addition to %s failed\n' "$list"
	fi
    done
    local l
    for l in "$WORKDIR/list.src".*; do
	[ "$l" != "$WORKDIR/list.src.*" ] || continue
	sort -u -o "files/${l##*/}" "files/${l##*/}" "$l"
    done
    return $rc
}

do_del_package() {
    local rc=0
    local  n l
    for n in $(quote "$@"); do
	lists="$(grep -l "^$n[[:space:]]" files/list.src.*)" || continue
	for l in $lists; do
	    if [ -n "$force_component" ]; then
		[ "$force_component" = "${l##*\.}" ] || continue
	    fi
	    subst "/^$n[[:space:]].*$/d" "$l" || rc=1
	    if [ -n "$verbose" ]; then
		printf 'removing %s from %s ' "$n" "$l"
		cut -f1 files/list.src.* | grep -qsxF "$n"  && echo "failed" || echo "succesed"
	    fi
	done
    done
    return $rc
}

TEMP=`getopt -n $PROG -o a,A,d,D,h,i,l:,v -l add,delete,help,interactive,list:,verbose -- "$@"` || Usage
eval set -- "$TEMP"

while :; do
    case $1 in
	-a| --add) action='add'
	    ;;
	-A)
	    action='add'
	    interactive=1
	    verbose=-v
	    ;;
	-d| --delete) action='del'
            ;;
	-D)
	    action='del'
	    interactive=1
	    verbose=-v
	    ;;
	-l| --list) shift
	    [ -z "$1" ] || force_component="$1"
	    ;;
	-i| --interactive) interactive=1
	    ;;
	-v| --verbose) verbose=-v
	    ;;
	-h| --help) Usage 0
	    ;;
	--) shift; break
	    ;;
	*) Fatal "unrecognized option: $1"
	    ;;
    esac
    shift
done

pkgs="$@"
if [ -n "$interactive" ]; then
    arg=
    while read arg; do
        pkgs="$pkgs $arg"
    done
fi

# At least one argument, please.
if ! [ "${#pkgs}" -ge 1 ]; then
	Info "at least one argument is required."
	Usage
fi

trap exit_handler HUP INT QUIT TERM EXIT
WORKDIR="$(mktemp -d -t "$PROG.XXXXXXXXXX")"

[ -n "$action" ] || Usage 1
case $action in 
    add) do_add_package $pkgs ;;
    del) do_del_package $pkgs ;;
esac
