#!/bin/bash
set -euo pipefail

SSTATE_DIR=""
BB_HASHCLIENT=""
BB_HASHSERVER=""

ALIVE_DB_MARK="alive"
CLEAN_DB="false"
THRESHOLD_AGE="3600"

function help() {
    cat <<HELP_TEXT
Usage: $0 --sstate-dir path --hashclient path --hashserver-address address \
[--mark value] [--clean-db] [--threshold-age seconds]

Auxiliary script remove unused or no longer relevant entries from the hashequivalence database, based
on the files available on the sstate directory.

    -h | --help)               Show this help message and exit
    -a | --hashserver-adress)  bitbake-hashserver address
    -c | --hashclient)         Path to bitbake-hashclient
    -m | --mark)               Marker string to mark database entries
    -s | --sstate-dir)         Path to the sstate dir
    -t | --threshold-age)      Remove unused entries older than SECONDS old (default: 3600)
    --clean-db)                Remove all unmarked and unused entries from the database
HELP_TEXT
}

function argument_parser() {
    while [ $# -gt 0 ]; do
        case "$1" in
            -h | --help) help; exit 0 ;;
            -a | --hashserver-address) BB_HASHSERVER="$2"; shift ;;
            -c | --hashclient) BB_HASHCLIENT="$2"; shift ;;
            -m | --mark) ALIVE_DB_MARK="$2"; shift ;;
            -s | --sstate-dir) SSTATE_DIR="$2"; shift ;;
            -t | --threshold-age) THRESHOLD_AGE="$2"; shift ;;
            --clean-db) CLEAN_DB="true";;
            *)
                echo "Argument '$1' is not supported" >&2
                help >&2
                exit 1
                ;;
        esac
        shift
    done

    function validate_mandatory_argument() {
        local var_value="$1"
        local error_message="$2"

        if [ -z "$var_value" ]; then
            echo "$error_message"
            help >&2
            exit 1
        fi
    }

    validate_mandatory_argument "$SSTATE_DIR" "Please provide the path to the sstate dir."
    validate_mandatory_argument "$BB_HASHCLIENT" "Please provide the path to bitbake-hashclient."
    validate_mandatory_argument "$BB_HASHSERVER" "Please provide the address of bitbake-hashserver."
}

# -- main code --
argument_parser $@

# Mark all db sstate hashes
find "$SSTATE_DIR" -name "*.tar.zst" | \
sed 's/.*:\([^_]*\)_.*/unihash \1/' | \
$BB_HASHCLIENT --address "$BB_HASHSERVER" gc-mark-stream "$ALIVE_DB_MARK"

# Remove unmarked and unused entries
if [ "$CLEAN_DB" = "true" ]; then
    $BB_HASHCLIENT --address "$BB_HASHSERVER" gc-sweep "$ALIVE_DB_MARK"
    $BB_HASHCLIENT --address "$BB_HASHSERVER" clean-unused "$THRESHOLD_AGE"
fi
