#!/bin/sh

set -e

info() {
    echo "* $@" >&2
}

info2() {
    echo "  -" "$@" >&2
}

error() {
    echo "$PROGNAME: error:" "$@" >&2
    exit 1
}

warning() {
    echo "$PROGNAME: warning:" "$@" >&2
}

usage() {
    echo "$PROGNAME: usage:" "$0" "[ -i symbol_file ]" "[ -d debdir ]" "[ -s symboldir ]" package version "[ download_url ]" >&2
}


download() {
    # Download debs
    info "Downloading packages from $URL ..."
    wget -e robots=off --timestamping --no-directories --directory-prefix="$debdir" \
         --recursive --level=1 --no-parent --accept "$DEB_WILDCARD" "$URL"
}

extract_deb() {
    local deb tmpdir outdir
    local arch package version outfile

    deb="$1"
    tmpdir="$2"
    outdir="$3"

    info2 "Extracting `basename $deb` ..."
    dpkg-deb -e "$deb" "$tmpdir/DEBIAN"
    dpkg-deb -x "$deb" "$tmpdir"
}

dump_symbols() {
    local tmpdir outdir reffile
    local arch package version outfile outpatch

    tmpdir="$1"
    outdir="$2"
    reffile="$3"

    # Collection information about package
    package=$(sed -n '/^Package:/ {s/[^:]\+:[[:space:]]*\(.\+\)/\1/; p; q}' "$tmpdir/DEBIAN/control")
    version=$(sed -n '/^Version:/ {s/[^:]\+:[[:space:]]*\(.\+\)/\1/; p; q}' "$tmpdir/DEBIAN/control")
    arch=$(sed -n '/^Architecture:/ {s/[^:]\+:[[:space:]]*\(.\+\)/\1/; p; q}' "$tmpdir/DEBIAN/control")

    if [ "$arch" = "all" ]; then
        error "it does not make sense to process arch:all package ($deb)"
    fi

    if [ -n "$reffile" ]; then
	outfile="${package}_${arch}"
	info2 "[$arch] Dumping patch & symbol file as $outfile/$outfile.{patch,symbols} ..."
	pkgkde-gensymbols "-p$package" "-P$tmpdir" "-v$version" "-a$arch" \
	    -c1 "-I$reffile" -O"$outdir/$outfile.symbols" > "$outdir/$outfile.patch" || true
    else
	outfile="${package}_${arch}"
	info2 "[$arch] Dumping symbol file as $outfile ..."
	pkgkde-gensymbols "-p$package" "-P$tmpdir" "-v$version" "-a$arch" \
	    -c0 -I/dev/null "-O$outdir/$outfile"
    fi
}

# Process options
REFFILE=""
DEBDIR=""
SYMBOLDIR=""
while getopts "i:d:s:" name; do
    case "$name" in
	i)  REFFILE="$OPTARG" ;;
	d)  DEBDIR="$OPTARG" ;;
	s)  SYMBOLDIR="$OPTARG" ;;
	\?)  usage; exit 2 ;;
    esac
done

shift `expr $OPTIND - 1`

PACKAGE="$1"
VERSION="$2"
URL="$3"

DEB_WILDCARD="${PACKAGE}_${VERSION}_*.deb"
PROGNAME=`basename "$0"`

if [ -z "$PACKAGE" ] || [ -z "$VERSION" ]; then
    usage
    exit 2
fi

# Create directories to store downloaded debs and symbol files
debdir="${DEBDIR:-${PACKAGE}_${VERSION}_debs}"
symboldir="${SYMBOLDIR:-${PACKAGE}_${VERSION}_symbols}"

info "Selected directory for packages (*.deb):" "$debdir/"
if [ -n "$URL" ]; then
    if [ "${URL#http://}" != "$URL" ] || [ "${URL#ftp://}" != "$URL" ]; then
        if [ ! -d "$debdir" ]; then
            mkdir "$debdir"
        fi
        download
    else
        error "only http:// and ftp:// download URLs are supported"
    fi
fi

# Extract and process debs
c=0
if [ -d "$debdir" ]; then
    tmpdir=`mktemp -d --tmpdir=. tmpdeb.XXXXXX`
    rmdir "$tmpdir"
    if [ ! -d "$symboldir" ]; then
	mkdir "$symboldir"
    fi

    info "Selected temporary directory:" "$tmpdir/"
    info "Selected directory for symbol files:" "$symboldir/"
    for deb in `ls -1 "$debdir"/$DEB_WILDCARD 2>/dev/null | sort`; do
        mkdir "$tmpdir"
        extract_deb "$deb" "$tmpdir" "$symboldir"
        dump_symbols "$tmpdir" "$symboldir" "$REFFILE"
        rm -rf "$tmpdir"
        c=$(($c+1))
    done
fi

if [ $c -eq 0 ]; then
    error "no '$DEB_WILDCARD' binary packages found in $debdir/"
fi

info "$c arch specific symbol files dumped successfully to $symboldir/"
