#!/bin/bash

# if not called from systemd try to replicate mount unsharing on ctrl+c
# see: https://github.com/Zygo/bees/issues/281
if [ -z "${SYSTEMD_EXEC_PID}" -a -z "${UNSHARE_DONE}" ]; then
        UNSHARE_DONE=true
        export UNSHARE_DONE
        exec unshare -m --propagation private -- "$0" "$@"
fi

## Helpful functions
INFO(){ echo "INFO:" "$@"; }
ERRO(){ echo "ERROR:" "$@"; exit 1; }
YN(){ [[ "$1" =~ (1|Y|y) ]]; }

## Global vars
export BEESHOME BEESSTATUS
export WORK_DIR CONFIG_DIR
export CONFIG_FILE
export UUID AL16M AL128K

readonly AL128K="$((128*1024))"
readonly AL16M="$((16*1024*1024))"
readonly CONFIG_DIR=/etc/bees/

readonly bees_bin=$(realpath //usr/lib/bees/bees)

command -v "$bees_bin" &> /dev/null || ERRO "Missing 'bees' agent"

uuid_valid(){
    if uuidparse -n -o VARIANT $1 | grep -i -q invalid; then
        false
    fi
}

help(){
    echo "Usage: beesd [options] <btrfs_uuid>"
    echo "- - -"
    exec "$bees_bin" --help
}

for i in $("$bees_bin" --help 2>&1 | grep -E " --" | sed -e "s/^[^-]*-/-/" -e "s/,[^-]*--/ --/" -e "s/ [^-]*$//")
do
   TMP_ARGS="$TMP_ARGS $i"
done
IFS=" " read -r -a SUPPORTED_ARGS <<< $TMP_ARGS
NOT_SUPPORTED_ARGS=()
ARGUMENTS=()

for arg in "${@}"; do
    supp=false
    for supp_arg in "${SUPPORTED_ARGS[@]}"; do
        if [[ "$arg" == ${supp_arg}* ]]; then
            supp=true
            break
        fi
    done
    if $supp; then
        ARGUMENTS+=($arg)
    else
        NOT_SUPPORTED_ARGS+=($arg)
    fi
done

for arg in "${ARGUMENTS[@]}"; do
    case $arg in
        -h) help;;
        --help) help;;
    esac
done

for arg in "${NOT_SUPPORTED_ARGS[@]}"; do
    if uuid_valid $arg; then
        [ ! -z "$UUID" ] && help
        UUID=$arg
    fi
done

[ -z "$UUID" ] && help


FILE_CONFIG="$(grep -E -l '^[^#]*UUID\s*=\s*"?'"$UUID" "$CONFIG_DIR"/*.conf | head -1)"
[ ! -f "$FILE_CONFIG" ] && ERRO "No config for $UUID"
INFO "Find $UUID in $FILE_CONFIG, use as conf"
source "$FILE_CONFIG"


## Pre checks
{
    [ ! -d "$CONFIG_DIR" ] && ERRO "Missing: $CONFIG_DIR"
    [ "$UID" == "0" ] || ERRO "Must be run as root"
}


WORK_DIR="${WORK_DIR:-/run/bees/}"
MNT_DIR="${MNT_DIR:-$WORK_DIR/mnt/$UUID}"
BEESHOME="${BEESHOME:-$MNT_DIR/.beeshome}"
BEESSTATUS="${BEESSTATUS:-$WORK_DIR/$UUID.status}"
DB_SIZE="${DB_SIZE:-$((8192*AL128K))}"

INFO "Check: Disk exists"
if [ ! -b "/dev/disk/by-uuid/$UUID" ]; then
    ERRO "Missing disk: /dev/disk/by-uuid/$UUID"
fi

is_btrfs(){ [ "$(blkid -s TYPE -o value "$1")" == "btrfs" ]; }

INFO "Check: Disk with btrfs"
if ! is_btrfs "/dev/disk/by-uuid/$UUID"; then
    ERRO "Disk not contain btrfs: /dev/disk/by-uuid/$UUID"
fi

INFO "WORK DIR: $WORK_DIR"
mkdir -p "$WORK_DIR" || exit 1

INFO "MOUNT DIR: $MNT_DIR"
mkdir -p "$MNT_DIR" || exit 1

mount --make-private -osubvolid=5,nodev,noexec /dev/disk/by-uuid/$UUID "$MNT_DIR" || exit 1

if [ ! -d "$BEESHOME" ]; then
    INFO "Create subvol $BEESHOME for store bees data"
    btrfs sub cre "$BEESHOME"
fi

# Check DB size
{
    DB_PATH="$BEESHOME/beeshash.dat"
    touch "$DB_PATH"
    OLD_SIZE="$(du -b "$DB_PATH" | sed 's/\t/ /g' | cut -d' ' -f1)"
    NEW_SIZE="$DB_SIZE"
    if (( "$NEW_SIZE"%AL128K > 0 )); then
        ERRO "DB_SIZE Must be multiple of 128K"
    fi
    if (( "$OLD_SIZE" != "$NEW_SIZE" )); then
        INFO "Resize db: $OLD_SIZE -> $NEW_SIZE"
        rm -f "$BEESHOME/beescrawl.dat"
        truncate -s $NEW_SIZE $DB_PATH
    fi
    chmod 700 "$DB_PATH"
}

MNT_DIR="$(realpath $MNT_DIR)"

cd "$MNT_DIR"
exec "$bees_bin" "${ARGUMENTS[@]}" $OPTIONS "$MNT_DIR"
