#!/bin/bash

# Usage: run option -h to get help

PM3PATH=$(dirname "$0")
FULLIMAGE="fullimage.elf"
BOOTIMAGE="bootrom.elf"
# try pm3 dirs in current repo workdir
if [ -d "$PM3PATH/client/" ]; then
    CLIENT="$PM3PATH/client/proxmark3"
# try install dir
elif [ -x "$PM3PATH/proxmark3" ]; then
    CLIENT="$PM3PATH/proxmark3"
else
# hope it's installed somehow, still not sure where fw images are...
    CLIENT="proxmark3"
fi

function wait4proxmark_Linux {
    echo >&2 "[=] Waiting for Proxmark3 to appear..."
    while true; do
        PM3=$(find /dev/pm3-* /dev/ttyACM* 2>/dev/null | head -1)
        if [[ $PM3 != "" ]]; then
            break
        fi
        sleep .1
    done
    echo "$PM3"
}

function wait4proxmark_macOS {
    echo >&2 "[=] Waiting for Proxmark3 to appear..."
    while true; do
        PM3=$(find /dev/pm3-* /dev/tty.usbmodem* 2>/dev/null | head -1)
        if [[ $PM3 != "" ]]; then
            break
        fi
        sleep .1
    done
    echo "$PM3"
}

function wait4proxmark_Windows {
    echo >&2 "[=] Waiting for Proxmark3 to appear..."
    while true; do
        device=$(wmic path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2')
        if [[ $device != "" ]]; then
            PM3=${device/ */}
            break
        fi
        sleep .1
    done
    echo "$PM3"
}

function wait4proxmark_WSL {
    # Test presence of wmic
    wmic.exe computersystem get name >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "[!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)"
        exit 1
    fi

    echo >&2 "[=] Waiting for Proxmark3 to appear..."
    while true; do
        device=$(wmic.exe path Win32_SerialPort where "PNPDeviceID like '%VID_9AC4&PID_4B8F%'" get DeviceID,PNPDeviceID 2>/dev/null | awk 'NR==2')
        if [[ $device != "" ]]; then
            PM3=${device/ */}
            PM3="/dev/ttyS${PM3#COM}"
            break
        fi
        sleep .1
    done
    if [ -e "$PM3" ] && [ ! -w "$PM3" ]; then
        echo "[!!] We need to give current user read/write access to $PM3"
        sudo chmod 666 "$PM3"
    fi
    echo "$PM3"
}

SCRIPT=$(basename -- "$0")

if [ "$SCRIPT" = "pm3" ]; then
  CMD() { $CLIENT "$@"; }
  HELP() {
      cat << EOF
Quick helper script for proxmark3 client when working with a Proxmark device connected via USB

Description:
    The usage is the same as for the proxmark3 client, with the following differences:
     * the correct port name will be automatically guessed;
     * the script will wait for a Proxmark to be connected (same as option -w of the client).
    Don't use this script if you want to work offline or with the BT addon.

Usage:
    $SCRIPT [-f] [-c <command>]|[-l <lua_script_file>]|[-s <cmd_script_file>] [-i]

See "$CLIENT -h" for more details on options.
EOF
  }
elif [ "$SCRIPT" = "pm3-flash" ]; then
  CMD() {
      ARGS=("$1" "--flash")
      shift;
      while [ "$1" != "" ]; do
          if [ "$1" == "-b" ]; then
              ARGS+=("--unlock-bootloader")
          else
              ARGS+=("--image" "$1")
          fi
          shift;
      done
      $CLIENT ${ARGS[@]};
  }
  HELP() {
      cat << EOF
Quick helper script for flashing a Proxmark device via USB

Description:
    The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed.
    If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".

Usage:
    $SCRIPT [-b] image.elf [image.elf...]

Options:
    -b         Enable flashing of bootloader area (DANGEROUS)

Example:
     $SCRIPT -b bootrom.elf fullimage.elf
EOF
  }
elif [ "$SCRIPT" = "pm3-flash-all" ]; then
  CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; }
  HELP() {
      cat << EOF
Quick helper script for flashing a Proxmark device via USB

Description:
    The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed.
    If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".

Usage:
    $SCRIPT
EOF
  }
elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then
  CMD() { $CLIENT "$1" "--flash" "--image" "$FULLIMAGE"; }
  HELP() {
      cat << EOF
Quick helper script for flashing a Proxmark device via USB

Description:
    The correct port name will be automatically guessed and the stock firmware image will be flashed.
    If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".

Usage:
    $SCRIPT
EOF
  }
elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then
  CMD() { $CLIENT "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; }
  HELP() {
      cat << EOF
Quick helper script for flashing a Proxmark device via USB

Description:
    The correct port name will be automatically guessed and the stock bootloader will be flashed.
    If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".

Usage:
    $SCRIPT
EOF
  }
else
  echo "[!!] Script ran under unknown name, abort: $SCRIPT"
  exit 1
fi
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    HELP
    exit 0
fi
HOSTOS=$(uname | awk '{print toupper($0)}')
if [ "$HOSTOS" = "LINUX" ]; then
    if uname -a|grep -q Microsoft; then
        PORT=$(wait4proxmark_WSL)
    else
        PORT=$(wait4proxmark_Linux)
    fi
elif [ "$HOSTOS" = "DARWIN" ]; then
    PORT=$(wait4proxmark_macOS)
elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then
    PORT=$(wait4proxmark_Windows)
else
    echo "[!!] Host OS not recognized, abort: $HOSTOS"
    exit 1
fi
if [ "$PORT" = "" ]; then
    echo "[!!] No port, abort"
    exit 1
fi

CMD "$PORT" "$@"
exit $?