#!/bin/sh -efu

etc_dir=/etc/sisyphus-updates
var_dir=/var/lib/sisyphus-updates

mirror_dir=/etc/apt/mirrors
repository_dir=/etc/apt/repositories

sourceslist_file="$var_dir/sources.list"
aptconf_file="$var_dir/apt.conf"

rpm_arch="$(rpm --eval '%_host_cpu')"

avahi_cmd="/usr/bin/avahi-browse"
avahi_cmd_args="-prtk"

. shell-quote

source_line()
{
    local repo="$1";shift
    local mirror_path="$1";shift

    repo_file="$repository_dir/$repo.desktop"

    [ -s "$repo_file" ] ||
	fatal "no repository definiton found ($repo_file)"

    [ "$mirror_repolist" = ";;" -o -z "${mirror_repolist##*;$repo;*}" ] ||
	fatal "mirror have no support for this repository"

    local repo_noarch="$(shell_config_get "$repo_file" X-Has-Noarch)"

    local repo_sign="$(shell_config_get "$repo_file" X-Sign)"
    local repo_path="$(shell_config_get "$repo_file" X-Path)"
    local repo_comps="$(shell_config_get "$repo_file" X-Components)"

    printf 'rpm [%s] %s%s %s %s\n' "$repo_sign" "$mirror_path" "$repo_path" "$rpm_arch" "$repo_comps"
    [ "$repo_noarch" != "yes" ] ||
	printf 'rpm [%s] %s%s %s %s\n' "$repo_sign" "$mirror_path" "$repo_path" "noarch" "$repo_comps"
}

mirror_best_url()
{
    local mirror_url=
    for proto in X-HTTP-URI X-RSYNC-URI X-FTP-URI; do
	mirror_url="$(shell_config_get "$1" "$proto")"
	[ -z "$mirror_url" ] || break
    done

    [ -n "$mirror_url" ] ||
	fatal "no mirror url was found"

    echo "$mirror_url$(shell_config_get "$1" X-Path)"
}

txt_record()
{
    echo "$2"|sed -n "s/\(^\|.*[[:space:]]\)\"$(quote_sed_regexp "$1")=\([^\"]*\)\".*/\2/p"
}

avahi_source_line()
{
    local ip="$1"
    local avahi_repo="$(txt_record r "$2")"
    local avahi_arch=" $(txt_record a "$2") "
    local avahi_mirror="$(txt_record m "$2")"
    local avahi_custom_url="$(txt_record u "$2")"
    local avahi_repolist=" $repolist "

    #doen't support our arch
    [ -z "${avahi_arch##* $rpm_arch *}" ] || return 0

    #not compatible repository
    [ -z "${avahi_repolist##* $avahi_repo *}" ] || return 0

    local avahi_mirror_path=

    if [ "$avahi_mirror" = "custom" ];then
	avahi_mirror_path="$avahi_custom_url"
	[ -n "${avahi_mirror_path##/*}" ] ||
	    avahi_mirror_path="ftp://$ip$avahi_mirror_path"
    else
	local avahi_mirror_file="$mirror_dir/$avahi_mirror.desktop"
	[ -s "$avahi_mirror_file" ] ||
	    fatal "no mirror definiton found ($avahi_mirror_file)"

	local avahi_mirror_repolist=";$(shell_config_get "$avahi_mirror_file" X-Repositories);"
	[ "$mirror_repolist" = ";;" -o -z "${avahi_mirror_repolist##*;$avahi_repo;*}" ] ||
	    fatal "mirror have no support for this repository"

	avahi_mirror_path="$(mirror_best_url "$avahi_mirror_file")"
    fi

    source_line "$avahi_repo" "$avahi_mirror_path"
}

discover_domains() {
    "$avahi_cmd" -Dpt | while read; do
	printf '%s\n' "${REPLY##*;}"
    done
}

avahi_process_domain() {
    "$avahi_cmd" -prtk ${1+-d "$1"} _apt._tcp|
	while IFS=';' read prefix iface proto name type somefield hostname ip port data; do
	    [ "$prefix" = '=' ] || continue
	    avahi_source_line "$ip" "$data"
	done
}

. shell-error
. shell-config
. $etc_dir/sisyphus-updates.conf

[ "$mode" = "none" ] && exit 0

[ -n "$mirror" ] ||
    fatal "no mirror defined"

### create apt.conf
cat>"$aptconf_file"<<EOF
Dir::Etc::Main "/dev/null";
Dir::Etc::Parts "/var/empty";
Dir::Etc::SourceParts "/var/empty";
Dir::Etc::SourceList "$var_dir/sources.list";

Dir::State "$var_dir/apt-state";
Dir::Cache "$var_dir/apt-cache";
$(cat /etc/apt/apt.conf)
EOF

mkdir -p -- \
    "$var_dir/apt-state/lists/partial" \
    "$var_dir/apt-cache/archives/partial"

### create sources.list

mirror_path=
mirror_repolist=";;"

if [ "$mode" = "local" ];then
    [ -x "$avahi_cmd" ] ||
	fatal "$avahi_cmd is not installed"

    avahi_process_domain >"$sourceslist_file"
    discover_domains | while read domain; do
	    avahi_process_domain "$domain"
	done >>"$sourceslist_file"
else
    ## mirror info
    if [ "$mirror" = "custom" ];then
	mirror_path="$custom_url"
    else
	mirror_file="$mirror_dir/$mirror.desktop"
	[ -s "$mirror_file" ] ||
	    fatal "no mirror definiton found ($mirror_file)"

	mirror_repolist=";$(shell_config_get "$mirror_file" X-Repositories);"
	mirror_path="$(mirror_best_url "$mirror_file")"
    fi

    ## repo info
    for repo in $repolist; do

	[ "$mirror_repolist" = ";;" -o -z "${mirror_repolist##*;$repo;*}" ] ||
	    fatal "mirror have no support for this repository"

	source_line "$repo" "$mirror_path"
    done >"$sourceslist_file"
fi

[ -s "$sourceslist_file" ] || exit 0

### run apt
APT_CONFIG="$aptconf_file" apt-get update
APT_CONFIG="$aptconf_file" apt-get -y dist-upgrade</dev/null
APT_CONFIG="$aptconf_file" apt-get clean
