#!/bin/sh
#
# $HGsource$
# $Revision$ $Date$ $Author$
#
# $HGpath$
#

VERSION=@@VERSION@@

#
# Local repository with
# non-public packages and/or ports with changed OPTIONS (i.e. not using the
# defaults)
#
: ${LOCAL_REPO:=LocalRepo}
#
# Local repository with ports with default OPTIONS (i.e. unchanged)
# but newer than the packages in the "FreeBSD" repository.
# Some sort of a fast-track repository.
#
: ${LOCALBSDPORTS_REPO:=LocalBSDPorts}
#
# The official FreeBSD binary repository
#
: ${FREEBSD_REPO:=FreeBSD}
#
# Directly installed from ports
#
: ${PORTS_DIRECT_INSTALLED_REPO:=unknown-repository}

get_remote_repo_versions() {
    local _repo _data _rv

    _repo=$1

    _data=$(pkg version -U -R -r ${_repo} -v)
    _rv=$?
    eval remote_${_repo}_versions=\"\${_data}\"
    return ${_rv}
}

get_remote_repo_data() {
    local _repo _name _rversions _rfqp _rl _rdescr

    _repo=$1
    _name=$2

    eval _rversions=\"\${remote_${_repo}_versions}\"
    while read _rfqp _rl _rdescr ; do
        if [ ${_rfqp%-*} = ${_name} ] ; then
            eval remote_${_repo}_label=\"\${_rl}\"
            eval remote_${_repo}_descr=\"\${_rdescr}\"
            return 0
        fi
    done <<EOF884657
${_rversions}
EOF884657
    eval remote_${_repo}_label=""
    eval remote_${_repo}_descr=""
    return 1
}

get_local_index_versions() {
    local_index_versions=$(pkg version -I -v)
}

get_repo_for_package() {
    local _name _n _v _r

    _name=$1

    while read _n _v _r ; do
        if [ ${_name} = ${_n} ] ; then
            repository=${_r}
            return 0
        fi
    done <<EOF223777
${installed_data}
EOF223777
    return 1
}

assert_local_version() {
    local _name _version _n _v _r

    _name=$1
    _version=$2

    while read _n _v _r ; do
        if [ ${_name} = ${_n} ] ; then
            if [ ${_version} != ${_v} ] ; then
                return 1
            else
                return 0
            fi
        fi
    done <<EOF223
${installed_data}
EOF223
    return 2
}

print_title() {
    local _package _repo

    _package=$1
    _repo=$2
    if [ -z "${title_printed}" ] ; then
        echo "${_package}    (${_repo})"
        title_printed=yes
    fi
}


alldata_flag=""
alldata_LocalBSDPorts_flag=""
alldata_LocalRepo_flag=""
short_flag=""
verbose_flag=""

while getopts "Aasv" _opt ; do
    case ${_opt} in
        A)
            # print for every package the status of all repositories
            alldata_flag=1
            alldata_LocalBSDPorts_flag=1
            alldata_LocalRepo_flag=1
            ;;
        a)
            # print the data of all repos that have the package
            alldata_flag=1
            ;;
        s)
            # "short" output: if installed from FreeBSD repo: don't
            # report if only the index is newer
            short_flag=1
            ;;
        v)
            # print all titles and repo of every installed always
            verbose_flag=1
            ;;
        \?)
            exit 2
            ;;
        *)
            echo "option handling failed" >&2
            exit 2
            ;;
    esac
done

if [ -n "${short_flag}" -a -n "${alldata_flag}" ]; then
    echo "the -s option cannot be combined with -A or -a" >&2
    exit 2
fi

installed_packages=$(pkg query '%n')
installed_data="$(pkg query '%n %v %R' $installed_packages)"

get_remote_repo_versions ${LOCAL_REPO}
get_remote_repo_versions ${LOCALBSDPORTS_REPO}
get_remote_repo_versions ${FREEBSD_REPO}
get_local_index_versions

while read lfqp llabel ldescr ; do
    _installed_name=${lfqp%-*}
    _installed_version=${lfqp##*-}
    title_printed=""
    get_repo_for_package ${_installed_name}
    if [ -n "${verbose_flag}" ] ; then
        print_title "${lfqp}" "${repository}"
    fi
    if ! assert_local_version ${_installed_name} ${_installed_version} ; then
        echo "Assertion failed: $lfqp ${_installed_name} ${_installed_version} ${llabel}" >&2
        exit 1
    fi
    get_remote_repo_data ${LOCAL_REPO} ${_installed_name}
    get_remote_repo_data ${LOCALBSDPORTS_REPO} ${_installed_name}
    get_remote_repo_data ${FREEBSD_REPO} ${_installed_name}
    if [ \( -n "${alldata_flag}" \) -o \( \( "${llabel}" != '?' -a "${llabel}" != '=' \) -o \( "${remote_FreeBSD_label}" != '?' -a "${remote_FreeBSD_label}" != '=' \) -o \( "${remote_LocalBSDPorts_label}" != '?' -a "${remote_LocalBSDPorts_label}" != '=' \) -o \( "${remote_LocalRepo_label}" != '?' -a "${remote_LocalRepo_label}" != '=' \) \) -o \( "${repository}" = "${PORTS_DIRECT_INSTALLED_REPO}" \) ]; then
        _print_detail=""
        if [ -n "${short_flag}" ]; then
            #
            # NOTE: -s and -A/-a are incompatible: so "alldata_XXX" needs not
            #       to be checked!
            #
            if [ "${repository}" != "${FREEBSD_REPO}" -o "${llabel}" != '<' -o "${remote_FreeBSD_label}" != '=' -o "${remote_LocalRepo_label}" != '?' -o "${remote_LocalBSDPorts_label}" != '?' ]; then
                _print_detail=1
            fi
        else
            _print_detail=1
        fi
        if [ -n "${_print_detail}" ]; then
            print_title "${lfqp}" "${repository}"
            echo "   INDEX: ${llabel} ${ldescr}"
            echo "   FreeBSD: ${remote_FreeBSD_label} ${remote_FreeBSD_descr}"
            if [ \( -n "${alldata_LocalBSDPorts_flag}" \) -o \( "${remote_LocalBSDPorts_label}" != '?' \) ] ; then
                echo "   LocalBSDPorts: ${remote_LocalBSDPorts_label} ${remote_LocalBSDPorts_descr}"
            fi
            if [ \( -n "${alldata_LocalRepo_flag}" \) -o \( "${remote_LocalRepo_label}" != '?' \) ] ; then
                echo "   LocalRepo: ${remote_LocalRepo_label} ${remote_LocalRepo_descr}"
            fi
        fi
    fi
done <<EOF856661111299999
${local_index_versions}
EOF856661111299999
