#! /bin/bash

set -o pipefail
. `dirname -- ${BASH_SOURCE[0]}`/common_functions.sh
setup_trap
cd_top
check_fast_mode_flag

download_clang_format() {
    version=$1
    arch_and_os="$(uname -m)-$(uname)"
    archive=dist/clang-format.tar.gz

    # Adding more clang-format binaries requires uploading them to boxes.10gen
    # You can either get the clang-format binary from the llvm releases page
    # (https://github.com/llvm/llvm-project/releases) or compile clang-format yourself.
    # Place the binary in dist/ and confirm that s_clang_format runs correctly, then
    # tar a folder containing just the clang-format binary with the format:
    # clang-format-llvm-${version}-${arch_and_os}/
    #     clang-format
    # into a tarball named clang-format-llvm-${version}-${arch_and_os}.tar.gz
    # The tarball should extract using the tar command below.
    # This tarball can then be uploaded via a Jira request to the BUILD team.
    if [[ "$arch_and_os" =~ ^("aarch64-Linux"|"x86_64-Darwin"|"arm64-Darwin"|"x86_64-Linux")$ ]] ; then
        curl -s https://s3.amazonaws.com/boxes.10gen.com/build/clang-format-llvm-"$version"-"$arch_and_os".tar.gz -o $archive
        tar --strip=1 -C dist/ -xf $archive clang-format-llvm-"$version"-"$arch_and_os"/clang-format && rm $archive
        chmod +x ./dist/clang-format

        if [[ "$arch_and_os" =~ ^("x86_64-Darwin"|"arm64-Darwin")$ ]] ; then
            # Needed to get around the macOS code signing issue.
            xattr -c ./dist/clang-format
        fi
    else
         echo "$0: unsupported architecture and OS combination '$arch_and_os' to run clang_format"
         return 1
    fi
}

# Override existing Clang-Format versions in the PATH.
export PATH="${PWD}/dist":$PATH

# Check if Clang-Format is already available with the desired version.
desired_version="12.0.1"
if ! command -v clang-format &> /dev/null; then
    download_clang_format $desired_version || exit 1
elif ! clang-format --version | grep -q $desired_version; then
    download_clang_format $desired_version || exit 1
fi

# Users may need to manually approve binaries.
# If we're not allowed to run Clang-Format, let's exit (should be obvious from the dialog).
clang-format --version &> /dev/null || exit 1

# Parallel execution: if it's the main onvocation of the script, collect the file names
# to process and run them in subprocesses.
if is_main_run; then
    search=`find bench examples ext src test tools/checksum_bitflip -name '*.[ch]' \
        -o -name '*.cpp' | filter_if_fast`
    for f in `cat dist/s_clang_format.list`; do
        search=`echo "$search" | sed "\#$f#d"`
    done
    echo "$search" | do_in_parallel
    exit $?
fi

# A list of files provided: process them one by one.

# Don't format inplace with -i flag.
# We want to be able to detect modifications.
for f in "$@"; do
    cat "$f" | \
            clang-format --fallback-style=none | \
            python3 dist/s_comment.py > "$t" || exit 1
    if ! cmp -s "$f" "$t"; then
        if [[ -n "$S_RECURSE" ]] ; then
            echo "Modifying $f"
        fi
        cp "$t" "$f"
    fi
done
