#!/usr/bin/env bash
#
# Usage: install.sh [-v|--verbose] [--dry-run] [--interactive] [--list] [--udevdir /etc/] [--prefix $PREFIX] [GLOB]
#
# Description:
#     Installs the BPF programs known to this script into the prefix and
#     creates and installs a udev rule that will load these program when the device
#     is plugged in.
#
#     After running this script, unplug and re-plug the device.
#
#     To undo this script, run uninstall.sh with the same arguments.
#
# Arguments:
#     GLOB       ... An optional shell glob to limit the number of BPF programs
#                    to install. Note that this glob needs to be in quotes, e.g. "*XPPen*".
#                    If omitted, all BPF programs in this tarball are installed.
# Options:
#     --verbose  ... print debug output
#     --dry-run  ... only print commands, do not install
#     --interactive  ask for confirmation for each BPF to install
#     --list     ... print the BPF files this script can install
#     --prefix   ... prefix for all files (default: /usr/local)
#     --udevdir  ... path to the udev directory to install rules and hwdb files in

# Generated by {{pipeline_url}}

SCRIPT_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
PREFIX=/usr/local

BPFS=({% for bpf in bpfs %}"{{bpf.filename}}" {% endfor %})

usage () {
  # Prints anyhing from the first line that is '#\n' to the first empty line
  sed -n -e '/^#$/,/^$/s/^#[ ]\?//p' "${BASH_SOURCE[0]}"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --help)
      usage
      exit 0
      ;;
    --interactive)
      INTERACTIVE="y"
      shift;
      ;;
    --verbose|-v)
      set -x
      shift
      ;;
    --dry-run)
      echo "--dry-run given, nothing will be installed and no command is run"
      DRY_RUN="echo"
      shift
      ;;
    --list)
      for bpf in "${BPFS[@]}"; do
        echo "$bpf"
      done
      exit 0
      ;;
    --prefix)
      PREFIX=$2
      shift 2
      ;;
    --udevdir)
      UDEVDIR=$2
      shift 2
      ;;
    --*)
      usage
      exit 1
      ;;
    *)
      break;
      ;;
  esac
done

GLOB=""

if [ $# -gt 0 ]; then
  if [ $# -gt 1 ]; then
    usage
    exit 1
  fi
  GLOB=$1
  shift
fi

set -e

if [ -z "$UDEVDIR" ]; then
  case ${PREFIX%/} in
    /usr)
      UDEVDIR="/usr/lib"
      ;;
    *)
      UDEVDIR="/etc"
      ;;
  esac
fi

# Replace BINDIR with our given prefix but leave a marker in place so
# if this script is run twice we remove any previously added lines.
find ./ \
  -name "*.rules" \
  -exec \
    sed -i \
    -e "/.*#MARKER/,+1d" \
    -e "s|^#\?\(.*\)\(@@BINDIR@@\)\(.*\)|#\1\2\3\n#MARKER\n\1$PREFIX/bin\3|" \
    {} \;


echo "Using sudo to install files into $PREFIX. You may be asked for your password now"
dryrun_sudo="$DRY_RUN sudo"
{% for bpf in bpfs %}
# shellcheck disable=SC2053
if [[ -z "$GLOB" || "{{bpf.filename}}" = $GLOB ]]; then
  if [[ -n "$INTERACTIVE" ]]; then
    read -rp "Install {{bpf.filename}}? [y/N] " INSTALL_INTERACTIVE
  fi
  if [[ -z "$INTERACTIVE" || $INSTALL_INTERACTIVE = [yY] ]]; then
    $dryrun_sudo install -D -t "$PREFIX/{{bpf.dir}}" "$SCRIPT_DIR/{{bpf.path}}"
  fi
fi
{% endfor %}
# The following lines are generic and should be left as-is
{% for rule in udev_rules %}
$dryrun_sudo install -D -m 644 -t "$UDEVDIR"/udev/rules.d "$SCRIPT_DIR"/{{rule.path}}
{% endfor %}
{% for hwdb in hwdb_files %}
$dryrun_sudo install -D -m 644 -t "$UDEVDIR"/udev/hwdb.d "$SCRIPT_DIR"/{{hwdb.path}}
{% endfor %}
$dryrun_sudo install -D -t "$PREFIX/bin/" "$SCRIPT_DIR/bin/udev-hid-bpf"
$dryrun_sudo udevadm control --reload
$dryrun_sudo systemd-hwdb update
