#!/usr/bin/sh
# shellcheck disable=SC1090

# Add a package to the Freight library.

#/ Usage: freight add [-c <conf>] [-v] [-h] <package> <manager>/<distro>...
#/   -c <conf>, --conf=<conf> config file to parse
#/   -v, --verbose            verbose mode
#/   -e, --add-error          exit with error if package already added
#/   -h, --help               show this help message

set -e

usage() {
    grep "^#/" "$0" | cut -c"4-" >&2
    exit "$1"
}
while [ "$#" -gt 0 ]; do
    case "$1" in
        -c | --conf) CONF="$2" shift 2 ;;
        -c*) CONF="$(echo "$1" | cut -c"3-")" shift ;;
        --conf=*) CONF="$(echo "$1" | cut -c"8-")" shift ;;
        -v | --verbose) VERBOSE=1 shift ;;
        -e | --add-error) FREIGHT_ADD_ERROR="YES" shift ;;
        -h | --help) usage 0 ;;
        -*)
            echo "# [freight] unknown switch: $1" >&2
            usage 1
            ;;
        *) break ;;
    esac
done

. "/usr/share/freight/conf.sh"

# The non-option argument(s) following the last option are package files.
# Binary packages have only one but source packages require two or three.
# When the last of these is found, the remaining arguments are each assumed
# to be `<manager>/<distro>` pairs for this (source) package.
while [ "$#" -gt 0 ]; do
    case "$1" in
        *.deb | *.ddeb | *.dsc | *.orig.tar.gz | *.orig.tar.bz2 | *.orig.tar.xz | *.orig.tar.lzma | *.diff.gz | *.debian.tar.gz | *.debian.tar.bz2 | *.debian.tar.xz | *.debian.tar.lzma | *.tar.gz | *.tar.bz2 | *.tar.xz | *.tar.lzma)
            # shellcheck disable=SC2153
            PATHNAMES="$PATHNAMES $1" shift
            ;;
        *.build | *.changes) shift ;;
        *) break ;;
    esac
done
[ -z "$PATHNAMES" ] && usage 1
[ -z "$*" ] && usage 1

# Create a working directory on the same device as the Freight library and
# copy this package there.  This used to be a link but is now a copy because
# later Freight commands will rely on the link count being reduced to one.
mkdir -p "$VARLIB"
TMP="$(mktemp -d "$VARLIB/freight.$$.XXXXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf \"$TMP\"" EXIT INT TERM
for PATHNAME in $PATHNAMES; do
    cp "$PATHNAME" "$TMP/"
done

# Enter the Freight library directory so that items in `$@` may be given as
# absolute paths or as partial paths of the form `<manager>/<distro>` that
# are ultimately taken relative to the Freight library.
cd "$VARLIB"

# Add a file to the Freight library.  The arguments are FILENAME, DIRNAME, and
# PATHNAME.  The first two are given fairly directly to ln(1); the final one
# is used to create appropriate success or failure messages.
add() {
    if ln "$TMP/$1" "$2/$1" 2>"$TMP/ln"; then
        echo "# [freight] added $3 to $2${4+" as "}$4" >&2
    else
        if grep -q "File exists" "$TMP/ln"; then
            echo "# [freight] $2 already has $3${4+" as "}$4" >&2
        else
            cat "$TMP/ln" >&2
        fi
        if [ -n "$FREIGHT_ADD_ERROR" ]; then
            exit 2
        fi
    fi
}

# Hard link this package into every `<manager>/<distro>` given in `$@`.
# These links will later be used to compile the `Release` and `Packages`
# files in the Freight cache.
for PATHNAME in $PATHNAMES; do
    FILENAME="$(basename "$PATHNAME")"
    for DIRNAME in "$@"; do
        mkdir -p "$DIRNAME"
        case "$FILENAME" in
            *_*_*.deb | *_*_*.ddeb) add "$FILENAME" "$DIRNAME" "$PATHNAME" ;;
            *.deb | *.ddeb)
                . "/usr/share/freight/apt.sh"
                dpkg-deb -I "$TMP/$FILENAME" "control" >"$TMP/$FILENAME-control"
                DEBNAME="$(
                    apt_binary_name "$TMP/$FILENAME-control"
                )_$(
                    apt_binary_version "$TMP/$FILENAME-control"
                )_$(
                    apt_binary_arch "$TMP/$FILENAME-control"
                ).${FILENAME##*.}"
                add "$FILENAME" "$DIRNAME" "$PATHNAME" "$DEBNAME"
                ;;
            *) add "$FILENAME" "$DIRNAME" "$PATHNAME" ;;
        esac
    done
done

# vim: et:ts=4:sw=4
