#!/bin/sh

SOURCES_LIST="/etc/apt/sources.list /etc/apt/sources.list.d"
VENDORS_LIST="/etc/apt/vendors.list /etc/apt/vendors.list.d"

sp='[[:space:]]'
nsp='[^[:space:]]'
br='	'

_()
{
LANG=${in_language%%;*}.utf8 gettext "alterator-apt" "$1"
}

#turn off auto expansion
set -f

. /usr/share/alterator/build/backend3.sh

escape_string()
{
    sed -e 's,_,_5f,g' \
        -e 's,/,_2f,g' \
        -e 's, ,_20,g' \
        -e "s,$br,_09,g" \
        -e 's,:,_3a,g' \
	-e 's,?,_3f,g' \
	-e 's,&,_26,g' \
	-e 's,=,_3d,g'
}

quote_string()
{
    sed -e 's,[][)(-.^$|/\\+?*],\\&,g'
}

unescape_string()
{
    sed -e 's,_3a,:,g' \
	-e "s,_09,$br,g" \
	-e 's,_20, ,g' \
	-e 's,_2f,/,g' \
	-e 's,_5f,_,g' \
	-e 's,_3f,?,g' \
	-e 's,_26,&,g' \
	-e 's,_3d,=,g'
}

parse_source()
{
    sed -r\
    -e '\,#* *rpm,!d' \
    -e '\,^[[:space:]]*$,d'|
    while read -r line; do
	if printf %s "$line" |egrep -qs "(rpm|rpm-src)($sp+\[([^]]+)\])?$sp+cdrom:"; then
	    printf %s\\n "$line" |sed -r "s,^(#+)?$sp*(rpm|rpm-src)($sp+\[([^]]+)\])?$sp+(cdrom:\[[^]]+\]/)$sp+($nsp+)$sp+(.+)\$,\"\1\"$br\2$br\"\4\"$br\5$br\6$br\7,"
	else
	    printf %s\\n "$line" |sed -r "s,^(#+)?$sp*(rpm|rpm-src)($sp+\[([^]]+)\])?$sp+($nsp+)$sp+($nsp+)$sp+(.+)\$,\"\1\"$br\2$br\"\4\"$br\5$br\6$br\7,"
	fi
    done
}

print_source()
{
    local IFS="$br"
    while read state type sign uri arch components;do
	[ "$type" = "rpm" ] && htype="`_ "binary"`" || htype="`_ "source"`"
	[ "$state" = '""' ] && state="`_ "on"`" || state="`_ "off"`"
	
	printf '("%s" state "%s" type "%s" sign %s uri "%s" arch "%s" components "%s")\n' \
		"$(printf "%s$br%s$br%s$br%s" "$type" "$uri" "$arch" "$components"|escape_string)" \
		"$state" "$htype" "$sign" "$uri" "$arch" "$components"
    done
}

print_source2()
{
    local IFS="$br"
    while read state type sign uri arch components;do
	printf 'type "%s" sign %s uri "%s" arch "%s" components "%s"\n' \
	"$type" "$sign" "$uri" "$arch" "$components"
    done
}

print_arch()
{
    echo "$in__objects"|
    unescape_string|
	(
	    IFS="$br"
	    read -r type uri arch components
	    if [ "${uri#cdrom:}" = "$uri" ]; then
		for i in noarch i386 i586 i686 x86_64;do
		    printf '("%s")' "$i"
		done
	    else
		printf '("%s")' "$arch"
	    fi
	)
}

regex_source()
{
    printf "$sp*%s($sp+\[([^]]+)\])?$sp+%s$sp+%s$sp+%s\n" "$@"
}

regex_source2()
{
    local IFS="$br"
    echo "$in__objects"|
	unescape_string|
	quote_string |
	(read -r type uri arch components
	 echo "$type # $uri # $arch # $components" >&2
         regex_source "$type" "$uri" "$arch" "$components")
}

regex_process()
{
    find $SOURCES_LIST \
	-type f \
	-name '*.list' \
	-exec sed -i -r "$1" \{\} \+
}

parse_vendor()
{
    awk 'BEGIN { RS="simple-key"; }
	/Name/ && ! /Group/ {  if ($1 == "") next;
			       name=gensub(/"/, "", "g", $1);
			       desc=gensub(/.+Name[[:blank:]]+"([^"]+)".+$/, "\\1", "", $0);
    			       printf "(\"%s\" label \"(%s) %s\")\n",name,name,desc;
	}' $*
}


on_message()
{
	case "$in_action" in
		constraints)
			echo '('
			if [ "$in_orig_action" = "new" ]; then
				req="#t"
			else
				req="#f"
			fi
			printf 'state (label "%s")' "`_ "State"`"
			printf 'type (label "%s")' "`_ "Type"`"
			printf 'sign (label "%s")' "`_ "Signature"`"
			printf 'arch (label "%s")' "`_ "Architecture"`"
			printf 'uri (required %s label "%s")' "$req" "`_ "URI"`"
			printf 'components (required %s label "%s")' "$req" "`_ "Components"`"
			echo ')'
			;;
		list)
			echo '('
			case "${in__objects##*/}" in
			    avail_sign)
				local list=
				printf '("none" label "%s")' "`_ "No signature"`"
				find $VENDORS_LIST \
					-type f \
					-name '*.list' | 
				while read list ; do
				    parse_vendor "$list"
				done
				;;
			    avail_type)
				printf '("rpm" label "%s")' "`_ "Binary packages"`"
				printf '("rpm-src" label "%s")' "`_ "Source packages"`"
				;;
			    avail_arch)
				print_arch
				;;
			    avail_action)
				printf '("delete" label "%s")' "`_ "delete"`"
				printf '("enable" label "%s")' "`_ "enable"`"
				printf '("disable" label "%s")' "`_ "disable"`"
				;;
			    *)
				LANG=C
				find $SOURCES_LIST \
					-type f \
					-name '*.list' \
					-exec sort -rb \{\} \+|
				    parse_source|
				    print_source
				;;
			esac
			echo ')'
			;;
		new)
			local re="$(regex_source "$in_type" "$in_uri" "$in_arch" "$in_components")"
			if egrep -qs -r "^(#+)?$re" $SOURCES_LIST;then
			    printf '(error "%s")' "`_ "Same source already in list"`"
			else
			    [ "$in_sign" = "none" ] && in_sign="" || in_sign=" [$in_sign]"
			    echo "$in_type$in_sign $in_uri $in_arch $in_components" >>/etc/apt/sources.list
			    echo '()'
			fi
			;;
		read)
			echo '('
			if [ "$in__objects" != "/" ];then
			    egrep -hr "^(#+)?$(regex_source2)" $SOURCES_LIST|
				head -n1|
				parse_source |
				print_source2
			fi
			echo ')'
		    ;;
		write)
			if [ "$in__objects" != "/" ];then
			    local re="$(regex_source2)"
			    [ "$in_sign" = "none" ] && in_sign="" || in_sign=" [$in_sign]"
			    regex_process "s,^(#+)?$re,\1$in_type$in_sign $in_uri $in_arch $in_components,"
			fi
			echo '()'
			;;
		delete)
			if [ "$in__objects" != "/" ];then
			    local re="$(regex_source2)"
			    regex_process "\,^(#+)?$re, d"
			fi
			echo '()'
			;;
		enable)
			if [ "$in__objects" != "/" ];then
			    local re="$(regex_source2)"
			    regex_process "s,^#+($re),\1,"
			fi
			echo '()'
			;;
		disable)
			if [ "$in__objects" != "/" ];then
			    local re="$(regex_source2)"
			    regex_process "s,^($re),#\1,"
			fi
			echo '()'
			;;
		*)
			echo '#f'
			;;
	esac
}

message_loop

# vim: set ts=4 sw=4 sts=4:
