#!/usr/bin/env sh

# 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;;
        *) 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|*.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) add "$FILENAME" "$DIRNAME" "$PATHNAME";;
            *.deb)
                . "/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"
                ).deb"
                add "$FILENAME" "$DIRNAME" "$PATHNAME" "$DEBNAME";;
            *) add "$FILENAME" "$DIRNAME" "$PATHNAME";;
        esac
    done
done

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