#! /bin/bash
# vim: shiftwidth=4 tabstop=4 expandtab

subcommand__help() {
    if [[ -z "$2" ]] || [[ "$2" == "ls" ]]; then
        echo "$COMMAND ls [VM] [--json]"
        if [[ "$2" == "ls" ]]; then
            echo "  List VM volumes's locks"
            echo "    [VM]               VM name"
            echo "    -J|--json          JSON output"
        fi
    fi
    if [[ -z "$2" ]] || [[ "$2" == "add" ]]; then
        echo "$COMMAND add [VM] [lock ID]"
        if [[ "$1" == "details" ]] && [[ "$2" == "add" ]]; then
            echo "  Add a lock on VM's volumes"
            echo "    [VM]               VM name"
            echo "    [lock ID]          The lock ID (default: compose using date with the format" \
                                         "'$DEFAULT_LOCK_ID_FORMAT')"
        fi
    fi
    if [[ -z "$2" ]] || [[ "$2" == "rm" ]]; then
        echo "$COMMAND rm [VM] [lock ID]"
        if [[ "$1" == "details" ]] && [[ "$2" == "rm" ]]; then
            echo "  Remove locks on VM's volume"
            echo "    [VM]               VM name"
            echo "    [lock ID]          Only remove lock specified by ID"
            echo "                       (optional, default: remove all locks)"
        fi
    fi
}

subcommand__ls() {
    check_generate_script_not_supported
    local vm="" json=0 opt hyp locks
    for opt in "${@:1}"; do
        case $opt in
            -J|--json)
                json=1
                ;;
            *)
                if [[ -z "$vm" ]]; then
                    vm=$opt
                else
                    usage "Unknown parameter '$opt'"
                fi
                ;;
        esac
    done
    [[ -z "$vm" ]] && usage "VM name is missing"
    hyp=$( locate "$vm" )
    check_hyp "$hyp" || usage "Unknown VM $vm"

    locks=$(list_locks "$vm" "$hyp")
    if [[ $json -eq 1 ]]; then
        jq <<< "$locks"
        exit 0
    fi

    if [[ "$locks" == "[]" ]]; then
        echo "No lock found on volumes of VM $vm"
        exit 0
    fi

    print_json_table volume locker id address <<< "$locks"
}

subcommand__add() {
    local vm=$1 hyp volumes
    [[ -z "$vm" ]] && usage "VM name is missing"
    hyp=$( locate "$vm" )
    check_hyp "$hyp" || usage "Unknown VM $vm"
    local lock_id=$2
    [[ -z "$lock_id" ]] && lock_id=$( date +"$DEFAULT_LOCK_ID_FORMAT" )

    mapfile -t volumes < <( list_volumes "$vm" "$hyp" )
    for volume in "${volumes[@]}"; do
        echo "Locking $volume"
        run_external rbd lock add "$volume" "$lock_id" || fatal_error "Failed to lock volume $volume"
    done
}

subcommand__rm() {
    local vm=$1 lock_id=$2 hyp locks
    [[ -z "$vm" ]] && usage "VM name is missing"
    hyp=$( locate "$vm" )
    check_hyp "$hyp" || usage "Unknown VM $vm"

    locks=$(list_locks "$vm" "$hyp")
    if [[ "$locks" == "[]" ]]; then
        echo "No lock found on volumes of VM $vm"
        [[ -n "$lock_id" ]] && exit 1
        exit 0
    fi

    local lock volume id locker
    set_newline_ifs
    for lock in $( jq -c '.[]' <<< "$locks" ); do
        id=$( jq -r '.id' <<< "$lock" )
        [[ -n "$lock_id" ]] && [[ "$lock_id" != "$id" ]] && continue
        volume=$( jq -r '.volume' <<< "$lock" )
        locker=$( jq -r '.locker' <<< "$lock" )
        echo "Unlocking $volume (lock id: $id, locker: $locker)"
        run_external rbd lock rm "$volume" "$id" "$locker" || \
            fatal_error "Failed to remove lock $id (locker: $locker) on volume $volume"
    done
    restore_ifs
}

run_subcommand "${COMMAND_ARGS[@]}"
