#!/bin/sh

VERSION="2.0"

export LSPKG=1

print_help()
{
    printf "%s\n" "
Usage:
lspkg [-f|-F|-s|-n|-p] [-d|-D|-i|-r] [--] PROFID PACKAGES [lsrdd options]
lspkg --help|--version

    Tool to output names of installable packages, provided by working directory of any engine.
    See lspkg(1) man page for detailed description. See rdd(1) for generic package syntax 
    and lsrdd(1) for description of lsrdd utility.
    
    -f
        Print names of files instead of names for package database.
    -F
        Print verified full path names of packages instead of their names.
    -k
        Print key-value pairs: plain rdd name and verified relative path.
    -K
        Print key-value pairs: plain rdd name and verified full absolute path.
    -n
        Print full names for package database.
    -s
        Print base names without version.
    -p
        Print plain rdd names (default).
    -d
        Print dependency tree for given package set. CMD arguments included.
        The packages in output are not deployed.
    -D
        Print dependency tree for given package set. CMD arguments included.
        The output includes entire tree, whether the packages are currently deployed or not.
    -i
        Print names of packages, which are in direct dependencies of given package set.
        The output includes entire set, whether the packages are currently deployed or not.
    -m
        Print names of packages, which are in direct dependencies of given package set.
        The packages in output are not deployed.
    -r
        Print reverse dependencies of given package set.
    --status
        Print plain rdd name, build status and time.
    --
        Stop parsing lspkg options.
"
}

fatal_error()
{
    printf "%s\n" "$1" >& 2
    exit 1
}

lspkg_status()
{
    while read -r line_input <&0 ; do
        # must be synced with log_STATUS from corelib/api.sh
        status_file="${TMPDIR}/${line_input}/status"
        if test -f "${status_file}" ; then
            cat "${status_file}"
        else
            printf "%s None 0\n" "${line_input}"
        fi
    done
}

FILES=
FILENAMES=
SHORTNAMES=
FULLNAMES=
PLAINNAMES=1
KEYVALUES=
RELATIVEPATH=
MISSINGDEPS=
COMPLETEDEPS=
STRAIGHTDEPS=
STATUS=

while test -n "$1" ; do
    case "$1" in
        --help)
                print_help
                exit 0
            ;;
        --version)
                printf "%s\n" "${VERSION}"
                exit 0
            ;;
        --status)
            STATUS=1
            shift
            ;;
        -f)
            FILES=
            FILENAMES=1
            BASENAMES=
            FULLNAMES=
            PLAINNAMES=
            KEYVALUES=
            RELATIVEPATH=
            shift
            ;;
        -F)
            FILES=1
            FILENAMES=
            BASENAMES=
            FULLNAMES=
            PLAINNAMES=
            KEYVALUES=
            RELATIVEPATH=
            shift
            ;;
        -k)
            FILES=1
            FILENAMES=
            BASENAMES=
            FULLNAMES=
            PLAINNAMES=1
            KEYVALUES=1
            RELATIVEPATH=1
            shift
            ;;
        -K)
            FILES=1
            FILENAMES=
            BASENAMES=
            FULLNAMES=
            PLAINNAMES=1
            KEYVALUES=1
            RELATIVEPATH=
            shift
            ;;
        -s)
            FILES=
            FILENAMES=
            SHORTNAMES=1
            FULLNAMES=
            PLAINNAMES=
            KEYVALUES=
            RELATIVEPATH=
            shift
            ;;
        -n)
            FILES=
            FILENAMES=
            SHORTNAMES=
            FULLNAMES=1
            PLAINNAMES=
            KEYVALUES=
            RELATIVEPATH=
            shift
            ;;
        -p)
            FILES=
            FILENAMES=
            SHORTNAMES=
            FULLNAMES=
            PLAINNAMES=1
            KEYVALUES=
            RELATIVEPATH=
            shift
            ;;
        -d)
            MISSINGDEPS=1
            COMPLETEDEPS=
            STRAIGHTDEPS=
            STRAIGHTMISSINGDEPS=
            REVERSEDEPS=
            shift
            ;;
        -D)
            COMPLETEDEPS=1
            MISSINGDEPS=
            STRAIGHTDEPS=
            STRAIGHTMISSINGDEPS=
            REVERSEDEPS=
            shift
            ;;
        -i)
            STRAIGHTDEPS=1
            STRAIGHTMISSINGDEPS=
            COMPLETEDEPS=
            MISSINGDEPS=
            REVERSEDEPS=
            shift
            ;;
        -m)
            STRAIGHTDEPS=
            STRAIGHTMISSINGDEPS=1
            COMPLETEDEPS=
            MISSINGDEPS=
            REVERSEDEPS=
            shift
            ;;
        -r)
            REVERSEDEPS=1
            STRAIGHTDEPS=
            STRAIGHTMISSINGDEPS=
            COMPLETEDEPS=
            MISSINGDEPS=
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            break
            ;;
    esac
done

time_warning=
if test -n "${COMPLETEDEPS}" ; then
    depend_filter="resolve_rebuild complete"
    time_warning=1
elif test -n "${STRAIGHTDEPS}" ; then
    depend_filter="resolve_atom complete"
elif test -n "${STRAIGHTMISSINGDEPS}" ; then
    depend_filter="resolve_atom"
elif test -n "${MISSINGDEPS}" ; then
    depend_filter="resolve_rebuild"
elif test -n "${REVERSEDEPS}" ; then
    depend_filter="resolve_reverse"
    time_warning=1
else
    depend_filter=
fi

if test -n "${KEYVALUES}" ; then
    if test -n "${FILES}" && test -n "${PLAINNAMES}"; then
        if test -n "${RELATIVEPATH}" ; then
            pack_filter="pack_filter_pkgbinfiles_pairs_relative"
        else
            pack_filter="pack_filter_pkgbinfiles_pairs"
        fi
    fi
elif test -n "${FILENAMES}" ; then
    pack_filter="pack_filter_pkgbin"
elif test -n "${FILES}" ; then
    pack_filter="pack_filter_pkgbinfiles"
elif test -n "${SHORTNAMES}" ; then
    pack_filter="pack_filter_pkgbase"
elif test -n "${FULLNAMES}" ; then
    pack_filter="pack_filter_pkgname"
elif test -n "${STATUS}" ; then
    pack_filter="lspkg_status"
elif test -n "${PLAINNAMES}" ; then
    pack_filter=
fi

if test -z "${depend_filter}" -a -z "${pack_filter}" ; then
    lsrdd "${@}"
    exit $?
fi

if test -n "${time_warning}" ; then
    printf "%s\n" "Warning: the request may be time-consuming." >&2
fi

eval "$( dumprdd -g "${@}" )"
if test -z "${ANYAPI}" ; then
    fatal_error 'dumprdd failed. Check your rdd tools.'
fi

if test -n "${depend_filter}" ; then
    # handle possible errors here without single pipeline
    # depend filters wait inside full time anyways before any output, so it's no big deal
    results="$( list_parse "${rdd_list_entry}" | ${depend_filter} )"
    code=$?
    if test -z "${results}" ; then
        exit "${code}"
    fi
    if test -z "${pack_filter}" ; then
        pack_filter="cat"
    fi
    printf "%s\n" "${results}" | "${pack_filter}"
else
    list_parse "${rdd_list_entry}" | "${pack_filter}"
fi
