#!/usr/bin/env bash
export LC_ALL=C
set -e -o pipefail

# Source the common prelude, which:
#   1. Checks if we're at the top directory of the Monero repository
#   2. Defines a few common functions and variables
#
# shellcheck source=libexec/prelude.bash
source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"


###################
## Sanity Checks ##
###################

################
# Required non-builtin commands should be invokable
################

check_tools git realpath


#############
##  Clean  ##
#############

# Usage: under_dir MAYBE_PARENT MAYBE_CHILD
#
# If MAYBE_CHILD is a subdirectory of MAYBE_PARENT, print the relative path
# from MAYBE_PARENT to MAYBE_CHILD. Otherwise, return 1 as the error code.
#
# NOTE: This does not perform any symlink-resolving.
#
under_dir() {
    local relpath
    relpath="$(realpath --no-symlinks --relative-base="$1" "$2")"
    if [ -z "$relpath" ] || [ "$relpath" = "$2" ] || [ "$relpath" = "." ]; then
        return 1
    else
        echo "$relpath"
    fi
}

# Usage: dir_under_git_root MAYBE_CHILD
#
# If MAYBE_CHILD is under the current git repository and exists, print the
# relative path from the git repository's top-level directory to MAYBE_CHILD,
# otherwise, exit with an error code.
#
dir_under_git_root() {
    local rv
    rv="$(under_dir "$(git_root)" "$1")"
    [ -n "$rv" ] && echo "$rv"
}

shopt -s nullglob
found_precious_dirs_files=( "${version_base_prefix}"*/"${var_base_basename}/precious_dirs" ) # This expands to an array of directories...
shopt -u nullglob

exclude_flags=()

for precious_dirs_file in "${found_precious_dirs_files[@]}"; do
    # Make sure the precious directories (e.g. SOURCES_PATH, BASE_CACHE, SDK_PATH)
    # are excluded from git-clean
    echo "Found precious_dirs file: '${precious_dirs_file}'"

    # Exclude the precious_dirs file itself
    if dirs_file_exclude_fragment=$(dir_under_git_root "$(dirname "$precious_dirs_file")"); then
        exclude_flags+=( --exclude="/${dirs_file_exclude_fragment}/precious_dirs" )
    fi

    # Read each 'name=dir' pair from the precious_dirs file
    while IFS='=' read -r name dir; do
        # Add an exclusion flag if the precious directory is under the git root.
        if under=$(dir_under_git_root "$dir"); then
            echo "Avoiding ${name}: ${under}"
            exclude_flags+=( --exclude="/$under" )
        fi
    done < "$precious_dirs_file"
done

output="$(git clean --dry-run -xdff "${exclude_flags[@]}")"

if [[ -z "${output}" ]]; then
    echo "Nothing to clean."
    exit 0
fi

if [[ -z "${NO_CONFIRM}" ]]; then
    echo "${output}"
    read -p "Confirm deletion [y/N]: " confirm
    if [[ ! "${confirm}" =~ ^[Yy]$ ]]; then
        exit 0
    fi
fi

git clean -xdff "${exclude_flags[@]}"
