#!/usr/bin/env bash
set -euo pipefail

floppy_resolve_script_dir() {
    local dir share
    dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    if [[ -f "$dir/lib/common.sh" ]]; then
        printf '%s\n' "$dir"
        return 0
    fi
    share="${XDG_DATA_HOME:-${HOME:-}/.local/share}/floppy-utils"
    if [[ -f "$share/lib/common.sh" ]]; then
        printf '%s\n' "$share"
        return 0
    fi
    if [[ -f "/usr/local/share/floppy-utils/lib/common.sh" ]]; then
        printf '%s\n' "/usr/local/share/floppy-utils"
        return 0
    fi
    echo "floppy: cannot find lib/common.sh — run install.sh from the floppy-utils tree" >&2
    exit 1
}

FLOPPY_SCRIPT_DIR="$(floppy_resolve_script_dir)"
# shellcheck source=lib/common.sh
source "$FLOPPY_SCRIPT_DIR/lib/common.sh"
floppy_load_config

floppy_parse_size() {
    local size="${1:-$FLOPPY_DEFAULT_SIZE_KB}"
    case "$size" in
        360|720|1440) echo "$size" ;;
        360K|720K|1440K|1.44M|1.44m) echo "${size%K}" | sed 's/1.44M/1440/i' ;;
        *) floppy_die "invalid size: $size (use 360, 720, or 1440)" ;;
    esac
}

floppy_cmd_make() {
    local name="" size_kb="$FLOPPY_DEFAULT_SIZE_KB"

    while [[ $# -gt 0 ]]; do
        case "$1" in
            -s|--size)
                [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                size_kb="$(floppy_parse_size "$2")"
                shift 2
                ;;
            -h|--help)
                echo "Usage: floppy make [name] [-s 360|720|1440]"
                return 0
                ;;
            -*)
                floppy_die "unknown option: $1"
                ;;
            *)
                [[ -z "$name" ]] || floppy_die "unexpected argument: $1"
                name="$1"
                shift
                ;;
        esac
    done

    if [[ -z "$name" ]]; then
        name="$(floppy_random_name)"
    fi

    floppy_create_blank "$name" "$size_kb" >/dev/null
    floppy_info "created $(floppy_image_path_in_diskdir "$name")"
}

floppy_cmd_devices() {
    local verbose=0
    while [[ $# -gt 0 ]]; do
        case "$1" in
            -v|--verbose) verbose=1; shift ;;
            -h|--help)
                echo "Usage: floppy devices [-v]"
                return 0
                ;;
            *) floppy_die "unknown option: $1" ;;
        esac
    done

    local out
    out="$(floppy_list_devices "$verbose")"
    if [[ -z "$out" ]]; then
        echo "No removable block devices found."
        echo "Connect a USB floppy drive and run again."
        return 0
    fi
    echo "Removable block devices (candidates for burn):"
    echo "$out"
}

main() {
    local cmd="${1:-help}"
    shift || true

    case "$cmd" in
        make)
            floppy_cmd_make "$@"
            ;;
        attach|mount)
            local image_arg="" size_kb="$FLOPPY_DEFAULT_SIZE_KB" format="auto"
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -s|--size)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        size_kb="$(floppy_parse_size "$2")"
                        shift 2
                        ;;
                    --format) format=yes; shift ;;
                    --no-format) format=no; shift ;;
                    -h|--help)
                        echo "Usage: floppy attach [name|path] [-s SIZE] [--format|--no-format]"
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        [[ -z "$image_arg" ]] || floppy_die "unexpected argument: $1"
                        image_arg="$1"
                        shift
                        ;;
                esac
            done
            floppy_cmd_attach "$image_arg" "$size_kb" "$format"
            ;;
        detach|umount)
            [[ $# -ge 1 ]] || floppy_die "usage: floppy detach <name|mountpoint|loop>"
            floppy_cmd_detach "$1"
            ;;
        read|archive)
            local name="" device="" yes=0 force=0 strict=0
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -d|--device)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        device="$2"
                        shift 2
                        ;;
                    -y|--yes) yes=1; shift ;;
                    --force) force=1; shift ;;
                    --strict) strict=1; shift ;;
                    -h|--help)
                        echo "Usage: floppy read [name] [-d /dev/sdX] [-y] [--force] [--strict]"
                        echo "  Archives inserted floppy to FLOPPY_DISKDIR/<name>.img"
                        echo "  Default name: volume label, else mount dir name (e.g. disk), else random"
                        echo "  Uses dd conv=noerror,sync for bad sectors unless --strict"
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        [[ -z "$name" ]] || floppy_die "unexpected argument: $1"
                        name="$1"
                        shift
                        ;;
                esac
            done
            floppy_cmd_read "$name" "$device" "$yes" "$force" "$strict"
            ;;
        dump|copy)
            local output="" device="" yes=0 force=0 strict=0
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -o|--output)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        output="$2"
                        shift 2
                        ;;
                    -d|--device)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        device="$2"
                        shift 2
                        ;;
                    -y|--yes) yes=1; shift ;;
                    --force) force=1; shift ;;
                    --strict) strict=1; shift ;;
                    -h|--help)
                        echo "Usage: floppy dump -o FILE [-d /dev/sdX] [-y] [--force] [--strict]"
                        echo "  Raw sector-for-sector copy; use -o - for stdout"
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        floppy_die "unexpected argument: $1 (use -o FILE)"
                        ;;
                esac
            done
            [[ -n "$output" ]] || floppy_die "usage: floppy dump -o FILE [-d DEVICE]"
            floppy_cmd_dump "$output" "$device" "$yes" "$force" "$strict"
            ;;
        burn|write)
            local image="" device="" yes=0
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -d|--device)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        device="$2"
                        shift 2
                        ;;
                    -y|--yes) yes=1; shift ;;
                    -h|--help)
                        echo "Usage: floppy burn <image> [-d /dev/sdX] [-y]"
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        [[ -z "$image" ]] || floppy_die "unexpected argument: $1"
                        image="$1"
                        shift
                        ;;
                esac
            done
            [[ -n "$image" ]] || floppy_die "usage: floppy burn <image> [-d DEVICE] [-y]"
            floppy_cmd_burn "$image" "$device" "$yes"
            ;;
        devices|list-devices)
            floppy_cmd_devices "$@"
            ;;
        list|attached|ls)
            local verbose=0
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -v|--verbose) verbose=1; shift ;;
                    -h|--help)
                        echo "Usage: floppy list [-v]"
                        echo "  Loop-mounted .img files and physical floppy media in the drive"
                        return 0
                        ;;
                    *) floppy_die "unknown option: $1" ;;
                esac
            done
            floppy_cmd_list "$verbose"
            ;;
        refresh|rescan|reload)
            local device="" do_eject=0 do_mount=0 wait_secs=2
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -d|--device)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        device="$2"
                        shift 2
                        ;;
                    --eject) do_eject=1; shift ;;
                    --mount) do_mount=1; shift ;;
                    -w|--wait)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        wait_secs="$2"
                        shift 2
                        ;;
                    -h|--help)
                        cat <<'EOF'
Usage: floppy refresh [-d /dev/sdX] [--mount] [--eject] [-w SEC]

  Run after swapping floppies in the same USB drive (without unplugging USB).
  Unmounts stale filesystem state, flushes buffers, and re-probes media size/label.

  --mount   Mount the new disk via udisks when media is detected
  --eject   Call eject(1) first (some Mitsumi/USB FDD units need this)
  -w SEC    Wait before re-probe (default 2)
EOF
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        floppy_die "unexpected argument: $1"
                        ;;
                esac
            done
            floppy_cmd_refresh "$device" "$do_eject" "$do_mount" "$wait_secs"
            ;;
        disconnect|power-off|eject-usb)
            local device=""
            while [[ $# -gt 0 ]]; do
                case "$1" in
                    -d|--device)
                        [[ $# -ge 2 ]] || floppy_die "$1 requires a value"
                        device="$2"
                        shift 2
                        ;;
                    -h|--help)
                        cat <<'EOF'
Usage: floppy disconnect [-d /dev/sdX]

  Safely finish work with the USB floppy drive:
    1. Unmount any mounted volume on the device
    2. Flush block device buffers
    3. Power off via udisks (or eject as fallback)

  After success, unplug the USB cable. Use this when done for the day — not when
  swapping floppies (use "floppy refresh" instead).

Aliases: power-off, eject-usb
EOF
                        return 0
                        ;;
                    -*)
                        floppy_die "unknown option: $1"
                        ;;
                    *)
                        floppy_die "unexpected argument: $1"
                        ;;
                esac
            done
            floppy_cmd_disconnect "$device"
            ;;
        status)
            floppy_cmd_status
            ;;
        help|--help|-h)
            floppy_usage
            ;;
        *)
            floppy_die "unknown command: $cmd (try: floppy help)"
            ;;
    esac
}

main "$@"