#!/bin/bash

function show_help() {
    cat <<EOF
Usage: $0 [OPTIONS]

Options:
    -s, --enable-spdk          Enable SPDK
        --spdk-interrupt-mode  Enable SPDK interrupt mode
        --spdk-memory-size     SPDK memory size in MB
        --spdk-cpumask         SPDK CPU mask
        --spdk-no-hugepage     Disable SPDK hugepage usage
    -l, --spdk-log             SPDK log level
    -h, --help                 Show this help message and exit
EOF
    exit 0
}

function bind_dev() {
    mount --rbind /host/dev /dev
}

function bind_sys() {
    mount --rbind /host/sys /sys
}

function bind_lib_modules() {
    mount --rbind /host/lib/modules /lib/modules
}

function enable_tgtd() {
    echo "Enabling tgtd"
    tgtd -f 2>&1 | tee /var/log/tgtd.log &
}

function generate_nvme_hostid_and_hostnqn() {
    mkdir -p /etc/nvme

    local hostnqn=$(nvme gen-hostnqn)
    # hostnqn is generated from /sys/class/dmi/id/product_uuid according to the implementation of libnvme
    echo "$hostnqn" > /etc/nvme/hostnqn
    # Always generate the same hostid for the same hostnqn
    cat /sys/class/dmi/id/product_uuid > /etc/nvme/hostid
}

function enable_spdk_tgt() {
    local options=("$@")
    echo "Enabling spdk_tgt with options: ${options[*]}"
    spdk_tgt "${options[@]}" 2>&1 | tee -a /log/spdk_tgt.log &

    timeout=120  # Timeout in seconds
    interval=1  # Interval in seconds
    elapsed_time=0

    while [ $elapsed_time -lt $timeout ]; do
        if [ -S "/var/tmp/spdk.sock" ]; then
            echo "Socket file '/var/tmp/spdk.sock' found after $elapsed_time seconds."
            return 0  # Exit successfully if the file exists
        fi

        sleep $interval
        elapsed_time=$((elapsed_time + interval))
    done

    echo "Timeout reached. Socket file '/var/tmp/spdk.sock' not found."
    return 1
}

enable_spdk=0
spdk_options=()
instance_manager_options=()

while [[ $# -gt 0 ]]; do
    opt="$1"
    case $opt in
        -s|--enable-spdk)
            enable_spdk=1
            ;;
        -m|--spdk-cpumask)
            spdk_options+=("-m" "$2")
            shift
            ;;
        -s|--spdk-memory-size)
            spdk_options+=("--mem-size" "$2")
            shift
            ;;
        -g|--spdk-no-hugepage)
            spdk_options+=("--no-huge")
            ;;
        -l|--spdk-log)
            spdk_options+=("-L" "$2")
            shift
            ;;
        --spdk-interrupt-mode)
            spdk_options+=("--interrupt-mode")
            ;;
        -h|--help)
            show_help
            ;;
        *)
            instance_manager_options+=("$1")
            ;;
    esac
    shift
done

#### Main ####

if [ "$enable_spdk" -eq 1 ]; then
    mkdir -p /log
    touch /log/instance-manager-${DATA_ENGINE}.log
    touch /log/spdk_tgt.log
fi

bind_dev
bind_sys
bind_lib_modules
[ "$enable_spdk" -eq 0 ] && enable_tgtd
[ "$enable_spdk" -eq 1 ] && generate_nvme_hostid_and_hostnqn
[ "$enable_spdk" -eq 1 ] && enable_spdk_tgt "${spdk_options[@]}"

if [ "$enable_spdk" -eq 1 ]; then
    exec-logrotate
    exec longhorn-instance-manager "${instance_manager_options[@]}" 2>&1 | tee -a /log/instance-manager-${DATA_ENGINE}.log
else
    exec longhorn-instance-manager "${instance_manager_options[@]}"
fi
