#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
# Copyright (C) 2021 Arm Limited or its affiliates and Contributors. All rights reserved.

[[ "$TRACE" ]] && set -x
set -euo pipefail
shopt -s extglob

print_help() {
    echo 'Usage: elfshaker-store-all [FIND] <(git-list-between <date> <date> | ...)'
    echo ''
    echo 'Stores the directories read in on the standard input as snapshots. '
    echo 'This command will REMOVE ALL files in the elfshaker repository (except the repository data)!'
    echo ''
    echo 'Each line of the input should consist of two tokens: [DIR] [SNAPSHOT]. '
    echo 'The contents of each directory will be copied to the elfshaker repository and stored by elfshaker store SNAPSHOT. '
    echo ''
    echo 'The FIND argument is a shell command that will be executed. The output of the execution will '
    echo 'be passed to elfshaker store in the --files-from option.'
    echo ''
    echo 'Example:'
    echo "elfshaker-store-all 'find . -name *.o' <(git-list-between 01/01/2020 02/01/2020 | awk '{print" '"/path/to/builds/"$1 $2'"}')"
}

main() {
    if [ ! -d 'elfshaker_data' ]; then
        echo 'Not an elfshaker repository!'
        exit 1
    fi

    REPO="$(realpath .)"
    while read -r DIR TAG; do
        rm -r !('elfshaker_data') || true
        echo "Processing $DIR..."
        FILES="$(mktemp)"
        (cd "$DIR" && bash <<< "$1") > "$FILES"
        # mkdir and cp do not perform the check-if-exists and create-dir
        # operations as a single transaction on the filesystem and fail if the
        # directory happens to be created after the check but before the call to
        # mkdir(3). We run mkdir sequentially to avoid this problem and only
        # then we can run cp --parents concurrently and safely.
        xargs -a "$FILES" dirname | sort | uniq | xargs mkdir -p
        (cd "$DIR" && xargs -a "$FILES" -P8 -I{} cp --reflink=auto -a --parents {} "$REPO")
        elfshaker store "$TAG" --verbose
        rm "$FILES"
    done
}

case "${1:--h}" in
    -h | --help)
        print_help
        [ $# -ne 0 ]
        exit $?
        ;;
    *)
        main "$@"
        ;;
esac

