#!/bin/bash
# Types a string into a VM's graphical console via simulated keystrokes
# (virsh send-key), for driving a login prompt or terminal before SSH is
# available. Usage: type_into_vm.sh "string to type" [--enter]
set -euo pipefail
DOM="${VM_NAME:-cachyos}"
str="$1"

keyname() {
  local c="$1"
  case "$c" in
    a) echo KEY_A ;; b) echo KEY_B ;; c) echo KEY_C ;; d) echo KEY_D ;;
    e) echo KEY_E ;; f) echo KEY_F ;; g) echo KEY_G ;; h) echo KEY_H ;;
    i) echo KEY_I ;; j) echo KEY_J ;; k) echo KEY_K ;; l) echo KEY_L ;;
    m) echo KEY_M ;; n) echo KEY_N ;; o) echo KEY_O ;; p) echo KEY_P ;;
    q) echo KEY_Q ;; r) echo KEY_R ;; s) echo KEY_S ;; t) echo KEY_T ;;
    u) echo KEY_U ;; v) echo KEY_V ;; w) echo KEY_W ;; x) echo KEY_X ;;
    y) echo KEY_Y ;; z) echo KEY_Z ;;
    0) echo KEY_0 ;; 1) echo KEY_1 ;; 2) echo KEY_2 ;; 3) echo KEY_3 ;;
    4) echo KEY_4 ;; 5) echo KEY_5 ;; 6) echo KEY_6 ;; 7) echo KEY_7 ;;
    8) echo KEY_8 ;; 9) echo KEY_9 ;;
    " ") echo KEY_SPACE ;;
    "-") echo KEY_MINUS ;;
    "_") echo "SHIFT+KEY_MINUS" ;;
    "/") echo KEY_SLASH ;;
    ".") echo KEY_DOT ;;
    ":") echo "SHIFT+KEY_SEMICOLON" ;;
    "~") echo "SHIFT+KEY_GRAVE" ;;
    "=") echo KEY_EQUAL ;;
    ">") echo "SHIFT+KEY_DOT" ;;
    "<") echo "SHIFT+KEY_COMMA" ;;
    "&") echo "SHIFT+KEY_7" ;;
    "!") echo "SHIFT+KEY_1" ;;
    "'") echo KEY_APOSTROPHE ;;
    "(") echo "SHIFT+KEY_9" ;;
    ")") echo "SHIFT+KEY_0" ;;
    "|") echo "SHIFT+KEY_BACKSLASH" ;;
    *) echo "UNMAPPED" ;;
  esac
}

for (( i=0; i<${#str}; i++ )); do
  c="${str:$i:1}"
  km=$(keyname "$c")
  if [[ "$km" == "UNMAPPED" ]]; then
    echo "Unmapped char: '$c'" >&2
    exit 1
  fi
  if [[ "$km" == SHIFT+* ]]; then
    k="${km#SHIFT+}"
    sudo virsh -c qemu:///system send-key "$DOM" --codeset linux KEY_LEFTSHIFT "$k"
  else
    sudo virsh -c qemu:///system send-key "$DOM" --codeset linux "$km"
  fi
  sleep 0.08
done

if [[ "${2:-}" == "--enter" ]]; then
  sleep 0.2
  sudo virsh -c qemu:///system send-key "$DOM" --codeset linux KEY_ENTER
fi
