#!/bin/bash
# aur-pkglist - print the AUR package list
[[ -v AUR_DEBUG ]] && set -o xtrace
set -o pipefail
argv0=pkglist
cache=${XDG_CACHE_HOME:-$HOME/.cache}/aurutils/$argv0
AUR_LOCATION=${AUR_LOCATION:-'https://aur.archlinux.org'}
PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

# default options
delay=300 mode=plain pkglist=packages update=0

http_last_modified() {
    awk -F', ' '/^[Ll]ast-[Mm]odified:/ {print $2}' "$1"
}

list_update() {
    curl -f "$1" --compressed --output "$2" --dump-header "$3"
}

list_headers() {
    curl -f "$1" --head -Ss
}

usage() {
    printf >&2 'usage: %s [-bt] [-FP pattern]\n' "$argv0"
    exit 1
}

source /usr/share/makepkg/util/parseopts.sh

opt_short='t:bFPSI'
opt_long=('pkgbase' 'search' 'info' 'fixed-strings' 'perl-regexp' 'plain' 'time:')
opt_hidden=('dump-options')

if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
    usage
fi
set -- "${OPTRET[@]}"

while true; do
    case "$1" in
        -b|--pkgbase)
            pkglist=pkgbase ;;
        -S|--search)
            mode=json; pkglist=packages-meta-v1.json ;;
        -I|--info)
            mode=json; pkglist=packages-meta-ext-v1.json ;;
        -F|--fixed-strings)
            mode=fixed ;;
        -P|--perl-regexp)
            mode=regex ;;
        --plain)
            mode=plain ;;
        -t|--time)
            shift; delay=$1 ;;
        --dump-options)
            printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
            printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
            exit ;;
        --) shift; break ;;
    esac
    shift
done

# default to regex if >0 arguments specified
if (( $# > 0 )) && [[ $mode == "plain" ]]; then
    mode=regex
fi

# packages.gz cache
install -dm700 "$cache"
cd "$cache" || exit

if [[ ! -s headers_$pkglist || ! -s $pkglist ]]; then
    update=1

elif [[ -s $pkglist ]]; then
    # TODO: use ETag when aurweb only updates it when required
    sec_l=$(http_last_modified "headers_$pkglist" | date -f - '+%s')
    sec_r=$(http_last_modified <(list_headers "$AUR_LOCATION/$pkglist.gz") | date -f - '+%s')

    if (( sec_l )) && (( sec_r )) && (( sec_r - sec_l > delay )); then
        update=1
    fi
fi

if (( update )); then
    list_update "$AUR_LOCATION/$pkglist.gz" "$pkglist" "headers_$pkglist"
fi

# pattern match
case $mode in
    plain) cat "$pkglist" ;;
    fixed) grep -F "$1" "$pkglist" ;;
    regex) grep -P "$1" "$pkglist" ;;
     json) jq -r "$1" "$pkglist" ;;
esac

# vim: set et sw=4 sts=4 ft=sh:
