#!/bin/sh

po_domain="alterator-pkg"
datadir=/etc/alterator/pkg-sources/
sourcelist="/etc/apt/sources.list /etc/apt/sources.list.d/*"

uri_re='^\(ftp\|http\|file\)://[a-zA-Z0-9._/-]\+$'
prefix_re="[[:space:]]*rpm[[:space:]]\+\([^[:space:]]\+[[:space:]]\+\)\?"
base_re="$prefix_re\([^[:space:]]\+\)"
all_re="^#\?$base_re"

. alterator-sh-functions
. shell-quote

### desktop-like files
desktop_awk()
{
    awk -f /usr/share/alterator-menu/desktop.awk \
	-v lang="$in_language" \
	"$@"
}

desktop_list()
{
    find $datadir -name '*.desktop'
}


### uri work

decode_uri()
{
    echo "$1"|
	sed \
	    -e 's,%20, ,g'
}

has_uri()
{
    local pattern="$pattern";shift

    local OLD_IFS="$IFS"
    local IFS=";"

    for i in $pattern; do
	    IFS="$OLD_IFS"
	    local postfix="$(decode_uri "$i")"
	    grep -qs "$all_re$(quote_sed_regexp "$postfix")\$" $sourcelist || return 1
    done
    return 0
}

has_uri1()
{
    local pattern="$1";shift
    local new_uri="$1";shift
    local postfix="$(decode_uri "${pattern##*;}")"

    postfix="$(quote_sed_regexp "$postfix")"
    new_uri="$(quote_sed_regexp "$new_uri")"

    grep -qs "^#\?$prefix_re$new_uri$postfix\$" $sourcelist
}

add_uri()
{
    local pattern="$1";shift
    local new_uri="$1";shift

    [ -n "${new_uri##/*}" ] || new_uri="file://$new_uri"

    if echo "$new_uri"|grep -qvs "$uri_re"; then
	write_error "`_ "Invalid or unsupported protocol. Should be http, ftp or file"`"
	return 1
    elif has_uri1 "$pattern" "$new_uri"; then
	write_error "`_ "Same source already exists"`"
	return 1
    fi

    local IFS=";"
    for i in $pattern; do
	local postfix="$(decode_uri "$i")"
	printf '#rpm %s%s\n' "$new_uri" "$postfix" >>/etc/apt/sources.list
    done

    return 0
}

delete_uri()
{
    local pattern="$1";shift
    local uri="$(quote_sed_regexp "$1")";shift

    local OLD_IFS="$IFS"
    local IFS=";"

    for i in $pattern; do
	    IFS="$OLD_IFS"
	    local postfix="$(decode_uri "$i")"
	    postfix="$(quote_sed_regexp "$postfix")"

	    sed "/^#\?$prefix_re$uri$postfix\$/ d" -i $sourcelist
    done
}

off_uri()
{
    local pattern="$1";shift

    local OLD_IFS="$IFS"
    local IFS=";"

    for i in $pattern; do
	    IFS="$OLD_IFS"
	    local postfix="$(decode_uri "$i")"
	    postfix="$(quote_sed_regexp "$postfix")"
	    sed "s/^$base_re$postfix\$/#rpm \1\2$postfix/" -i $sourcelist
    done
}

on_uri()
{
    local pattern="$1";shift
    local new_uri="$1";shift
    new_uri="$(quote_sed_regexp "$new_uri")"

    local OLD_IFS="$IFS"
    local IFS=";"

    for i in $pattern; do
	    IFS="$OLD_IFS"
	    local postfix="$(decode_uri "$i")"
	    postfix="$(quote_sed_regexp "$postfix")"
	    sed "s/^#$prefix_re$new_uri$postfix\$/rpm \1$new_uri$postfix/" -i $sourcelist
    done
}

read_uri()
{
    local pattern="$1";shift
    local postfix="$(decode_uri ${pattern##*;})" #use only one pattern
    local v="$(sed -n "s/^$base_re$(quote_sed_regexp "$postfix")\$/\2/p" $sourcelist|head -n1)" #"

    [ -n "$v" ] || v="inactive"
    echo "$v"
}

list_uri()
{
    local pattern="$1";shift
    local postfix="$(decode_uri ${pattern##*;})" #use only one pattern

    sed -n "s/$all_re$(quote_sed_regexp "$postfix")\$/\2/p" $sourcelist
}

### list/read


write_repository_item()
{
    local name="$1";shift
    local label="$1";shift
    local pattern="$1";shift

    has_uri "$pattern" || return

    local uri="$(read_uri "$pattern")"

    [ "$uri" != "inactive" ] || uri="`_ "inactive"`"

    write_enum_item "$name" "$label ($uri)"
}

first_repository()
{
    desktop_list|
	while read i; do
	local name="${i%%.desktop}"
	desktop_awk "$i"|
	    (read weight pattern help icon description; has_uri "$pattern" && echo "${name##*/}")
	done|
	head -n1
}

list_repository()
{
    desktop_list|
	while read i; do
	local name="${i%%.desktop}"
	desktop_awk "$i"|
	    (read weight pattern help icon description; write_repository_item "${name##*/}" "$description" "$pattern")
    done
}


list_mirror()
{
    [ -f "$datadir/$1.desktop" ] || return 0

    write_enum_item "inactive" "`_ "inactive"`"
    desktop_awk "$datadir/$1.desktop"|
	(read weight pattern help icon description;
	    list_uri "$pattern"|write_enum)
}

read_mirror()
{
    [ -f "$datadir/$1.desktop" ] || return 0

    desktop_awk "$datadir/$1.desktop"|
	(read weight pattern help icon description;
	    write_string_param label "$description"
	    write_string_param uri "$(read_uri "$pattern")")
}

write_mirror()
{
    local name="$1";shift
    local new_uri="$1";shift

    [ -n "$name" -a -n "$new_uri" ] || return 0
    [ -f "$datadir/$name.desktop" ] || return 0

    desktop_awk "$datadir/$name.desktop"|
	(read weight pattern help icon description;
	 off_uri "$pattern"
	 [ "$new_uri" = "inactive" ] || on_uri "$pattern" "$new_uri")
}

new_mirror()
{
    local name="$1";shift
    local new_uri="$1";shift

    [ -n "$name" -a -n "$new_uri" ] || return 0
    [ -f "$datadir/$name.desktop" ] || return 0

    desktop_awk "$datadir/$name.desktop"|
	(read weight pattern help icon description;
	 add_uri "$pattern" "$new_uri")
}

delete_mirror()
{
    local name="$1";shift
    local uri="$1";shift

    [ "$uri" != "inactive" ] || return 0

    [ -n "$name" -a -n "$uri" ] || return 0
    [ -f "$datadir/$name.desktop" ] || return 0

    desktop_awk "$datadir/$name.desktop"|
	(read weight pattern help icon description;
	 delete_uri "$pattern" "$uri")
}

on_message()
{
	case "$in_action" in
		list)
			[ -n "$in_name" ] || in_name="$(first_repository)"
			echo '('
			case "${in__objects}" in
			    avail_repository) list_repository;;
			    avail_mirror) [ -n "$in_name" ] && list_mirror "$in_name" ;;
			esac
			echo ')'
			;;
		read)
			[ -n "$in_name" ] || in_name="$(first_repository)"
			echo '('
			write_string_param name "$in_name"
			[ -n "$in_name" ] && read_mirror "$in_name"
			echo ')'
			;;
		write)
			if [ -n "$in_new" ]; then
			    new_mirror "$in_name" "$in_new_uri" || return 0
			elif [ -n "$in_delete" ]; then
			    delete_mirror "$in_name" "$in_uri"
			elif [ -n "$in_commit" ]; then
			    write_mirror "$in_name" "$in_uri"
			fi

			write_nop
			;;
		*)
			echo '#f'
			;;
	esac
}

message_loop
