#!/usr/bin/env bash

source "${PALUDIS_EBUILD_DIR}/echo_functions.bash"

old_set=$-
set -a
for f in ${PALUDIS_BASHRC_FILES}; do
    [[ -f "${f}" ]] && source "${f}"
done
[[ "${old_set}" == *a* ]] || set +a

LOCAL=
REMOTE=

TMPDIR=/var/tmp

FETCHER_OPTIONS=( )
UNPACK_OPTIONS=( )
RSYNC_OPTIONS=( )

while [[ $# -gt 0 ]]; do
    case "${1}" in

        --strip-components=*)
            UNPACK_OPTIONS[${#UNPACK_OPTIONS[@]}]=--tar-option="${1}"
            ;;

        --exclude=*)
            RSYNC_OPTIONS[${#RSYNC_OPTIONS[@]}]=--exclude
            RSYNC_OPTIONS[${#RSYNC_OPTIONS[@]}]="${1#*=}"
            ;;

        --exclude-from=*)
            RSYNC_OPTIONS[${#RSYNC_OPTIONS[@]}]=--exclude-from
            RSYNC_OPTIONS[${#RSYNC_OPTIONS[@]}]="${1#*=}"
            ;;

        --tmpdir=*)
            TMPDIR="${1#*=}"
            ;;

        --fetcher-option=*)
            FETCHER_OPTIONS[${#RSYNC_OPTIONS[@]}]="${1#*=}"
            ;;

        --tar-option=*)
            UNPACK_OPTIONS[${#UNPACK_OPTIONS[@]}]="${1}"
            ;;

        --rsync-option=*)
            RSYNC_OPTIONS[${#RSYNC_OPTIONS[@]}]="${1#*=}"
            ;;

        --help)
            PROTO="${0##*/do}"
            if [[ "${PROTO}" == tar+file ]]; then
                echo "    URL syntax: tar+file:///PATH"
            elif [[ "${PROTO}" == tar+http || "${PROTO}" == tar+https || "${PROTO}" == tar+ftp ]]; then
                echo "    URL syntax: ${PROTO}://[USERNAME[:PASSWORD]@]SERVER[:PORT]/PATH"
            else
                # This syncer can handle any protocol for which there
                # is a fetcher.  The user can symlink/copy this syncer
                # to enable support for other protocols, but we can't
                # give them much help with the syntax....
                PROTO="${PROTO#tar+}"
                echo "    URL syntax: tar+${PROTO}://[$( tr [:lower:] [:upper:] <<<"${PROTO}" )-URL]"
            fi

            echo "    Options:"
            echo "        --exclude=PATTERN               Use PATTERN as an exclude pattern"
            echo "        --exclude-from=FILE             Use FILE as a list of exclude patterns"
            echo "        --strip-components=N            Ignore the first N components of the"
            echo "                                          paths from the tarball"
            echo "        --tmpdir=DIR                    Use DIR as base directory for"
            echo "                                          temporary files (/var/tmp by default)"
            echo "        --fetcher-option=OPTION         Pass OPTION to the fetcher"
            echo "                                          (The standard fetchers do not"
            echo "                                           accept any options - this is only"
            echo "                                           useful with custom fetchers)"
            echo "        --rsync-option=OPTION           Pass OPTION to the local rsync"
            echo "        --tar-option=OPTION             Pass OPTION to tar"
            exit 0
            ;;

        --*)
            ewarn "${0}: unknown option '${1%%=*}'"
            ;;

        *)
            if [[ -z "${LOCAL}" ]]; then
                LOCAL="${1}"
            elif [[ -z "${REMOTE}" ]]; then
                REMOTE="${1}"
            else
                eerror "${0}: extra argument '${1}'"
                exit 1
            fi
            ;;

    esac
    shift
done

if [[ -z "${LOCAL}" ]]; then
    eerror "${0}: unspecified local repository directory"
    exit 1
elif [[ -z "${REMOTE}" ]]; then
    eerror "${0}: unspecified remote repository URL"
    exit 1
fi

URL="${REMOTE#tar+}"

PROTOCOL="${URL%%://*}"
if [[ -z "${PROTOCOL}" ]]; then
    eerror "'${REMOTE}' is not a valid URL"
    exit 1
fi

if [[ -e "${LOCAL}" && ! -d "${LOCAL}" ]]; then
    eerror "'${LOCAL}' exists but is not a directory"
    exit 1
fi

FETCHER=
FETCHER_NAME="do$( tr '[:upper:]' '[:lower:]' <<<"${PROTOCOL}" )"
for d in ${PALUDIS_FETCHER_DIRS:-${PALUDIS_EBUILD_DIR}/fetchers/}; do
    if [[ -x "${d}/${FETCHER_NAME}" ]]; then
        FETCHER="${d}/${FETCHER_NAME}"
        break
    fi
done

if [[ -z "${FETCHER}" ]]; then
    eerror "Could not find a fetcher for '${PROTOCOL}'"
    exit 1
fi

TEMP="$( mktemp -d -p "${TMPDIR}" paludis-tarsync-XXXXXX )" || exit $?
TARFILE="${URL##*/}"

"${FETCHER}" "${FETCHER_OPTIONS[@]}" "${URL}" "${TEMP}/${TARFILE}" || exit $?

UNPACKDIR="${TEMP}/repository"
mkdir "${UNPACKDIR}"
export PALUDIS_UNPACK_SUFFIXES="tar tar.gz,tgz,tar.Z tar.bz2,tbz2,tbz zip,ZIP,jar rar,RAR lha,LHa,LHA,lzh a,deb tar.lzma 7z,7Z tar.xz"
export PALUDIS_UNPACK_UNRECOGNISED_IS_FATAL=yes
export PALUDIS_UNPACK_FIX_PERMISSIONS=
( cd "${UNPACKDIR}" && "${PALUDIS_EBUILD_DIR}/utils/unpack" \
    "${UNPACK_OPTIONS[@]}" "${TEMP}/${TARFILE}" ) || exit $?

rm "${TEMP}/${TARFILE}"

if [[ -z "$( ls -A "${UNPACKDIR}" )" ]]; then
    eerror "No files were extracted (not an archive?)"
    rm -rf "${TEMP}"
    exit 1
fi

[[ -d "${LOCAL}" ]] || mkdir -p "${LOCAL}"
${RSYNC_WRAPPER} rsync --recursive --links --safe-links --perms --times \
    --compress --force --whole-file --delete --delete-after --stats --timeout=180 \
    ${PALUDIS_SYNC_FILTER_FILE:+--filter "merge ${PALUDIS_SYNC_FILTER_FILE}"} \
    --exclude=/.cache --progress "${RSYNC_OPTIONS[@]}" "${UNPACKDIR}/" "${LOCAL}/"
STATUS=${?}

rm -rf "${TEMP}"
exit ${STATUS}

