#!/bin/sh

set -e

usage () {
  if [ "$#" -eq "0" ]; then
    usage set_hostname enable_ssh set_wlan set_keymap set_timezone
    return 0
  fi
  echo "Usage: "
  for arg in "$@"; do
    case "$arg" in
      set_hostname)
        echo "  $0 set_hostname HOSTNAME"
        ;;
      import_ssh_id)
        echo "  $0 import_ssh_id USERID1 [USERID2]..."
        ;;
      enable_ssh)
        echo "  $0 enable_ssh [-k|--key-only]|[-p|--pass-auth] [-d|--disabled] [KEY_LINE1 [KEY_LINE2]...]"
        ;;
      set_wlan)
        echo "  $0 set_wlan [-h|--hidden] [-p|--plain] SSID [PASS [COUNTRY]]"
        ;;
      set_wlan_country)
        echo "  $0 set_wlan_country COUNTRY]"
        ;;
      set_keymap)
        echo "  $0 set_keymap KEYMAP"
        ;;
      set_timezone)
        echo "  $0 set_timezone TIMEZONE"
        ;;
    esac
  done
  }

set_hostname () (
  if [ "$#" -ne 1 ]; then
    usage set_hostname
    exit 1
  fi
  HOSTNAME="$1"
  raspi-config nonint do_hostname "$HOSTNAME"
  echo "$HOSTNAME" > /etc/hostname
)

FIRSTUSER=$(getent passwd 1000 | cut -d: -f1)
FIRSTUSERHOME=$(getent passwd 1000 | cut -d: -f6)
SSH_DIR="$FIRSTUSERHOME/.ssh"
AUTHORISED_KEYS_FILE="$SSH_DIR/authorized_keys"

add_ssh_keys () (
  if ! [ -d "$SSH_DIR" ]; then
    install -o "$FIRSTUSER" -g "$FIRSTUSER" -m 700 -d "$SSH_DIR"
  fi
  for key in "$@"; do
    echo "$key" >> "$AUTHORISED_KEYS_FILE"
  done
  if [ -f "$AUTHORISED_KEYS_FILE" ]; then
    chmod 600 "$AUTHORISED_KEYS_FILE"
    chown "$FIRSTUSER:$FIRSTUSER" "$AUTHORISED_KEYS_FILE"
  fi
)

enable_ssh () (
  ENABLE=1
  KEY_ONLY_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication no/'
  PASSAUTH_SED_STR='s/^[#\s]*PasswordAuthentication\s\+\S\+$/PasswordAuthentication yes/'
  for arg in "$@"; do
    if [ "$arg" = "-k" ] || [ "$arg" = "--key-only" ]; then
      sed -i "$KEY_ONLY_SED_STR" /etc/ssh/sshd_config
    elif [ "$arg" = "-p" ] || [ "$arg" = "--pass-auth" ]; then
      sed -i "$PASSAUTH_SED_STR" /etc/ssh/sshd_config
    elif [ "$arg" = "-d" ] || [ "$arg" = "--disabled" ]; then
      ENABLE=0
    else
      add_ssh_keys "$arg"
    fi
  done
  if [ "$ENABLE" = 1 ]; then
    systemctl -q enable ssh
  fi
)

set_wlan_country () (
  if [ "$#" -ne 1 ]; then
    usage set_wlan_country
    exit 1
  fi
  # shellcheck disable=SC2030
  COUNTRY="$1"
  raspi-config nonint do_wifi_country "$COUNTRY"
)


set_wlan () (
  HIDDEN="false"
  PLAIN=0
  for arg in "$@"; do
    # shellcheck disable=SC2031
    if [ "$arg" = "-h" ] || [ "$arg" = "--hidden" ]; then
      HIDDEN="true"
    elif [ "$arg" = "-p" ] || [ "$arg" = "--plain" ]; then
      PLAIN=1
    elif [ -z "${SSID+set}" ]; then
      SSID="$arg"
    elif [ -z "${PASS+set}" ]; then
      PASS="$arg"
    elif [ -z "${COUNTRY+set}" ]; then
      COUNTRY="$arg"
    else
      usage set_wlan
      exit 1
    fi
  done
  if [ -z "${SSID+set}" ]; then
    usage set_wlan
    exit 1
  fi

  if [ -n "$COUNTRY" ]; then
    set_wlan_country "$COUNTRY"
  fi

  CONNFILE=/etc/NetworkManager/system-connections/preconfigured.nmconnection
  UUID=$(uuid -v4)
  cat <<- EOF >${CONNFILE}
	[connection]
	id=preconfigured
	uuid=${UUID}
	type=wifi
	[wifi]
	mode=infrastructure
	ssid=${SSID}
	hidden=${HIDDEN}
	[ipv4]
	method=auto
	[ipv6]
	addr-gen-mode=default
	method=auto
	[proxy]
	EOF

  if [ ! -z "${PASS}" ]; then
    cat <<- EOF >>${CONNFILE}
	[wifi-security]
	key-mgmt=wpa-psk
	psk=${PASS}
	EOF
  fi

  # NetworkManager will ignore nmconnection files with incorrect permissions,
  # to prevent Wi-Fi credentials accidentally being world-readable.
  chmod 600 ${CONNFILE}
)

import_ssh_id () (
  SCRIPT='/var/lib/raspberrypi-sys-mods/import-ssh'
  if [ "$#" -eq 0 ]; then
    usage import_ssh_id
    exit 1
  fi
  if ! command -v ssh-import-id > /dev/null; then
    echo "ssh-import-id not available"
    exit 1
  fi
  mkdir -p "$(dirname "$SCRIPT")"
  # shellcheck disable=SC2094
  cat <<- EOF > "$SCRIPT"
	#!/bin/sh
	COUNTER=0
	while [ "\$COUNTER" -lt 10 ]; do
	  COUNTER=\$((COUNTER + 1))
	  if runuser -u \$(getent passwd 1000 | cut -d: -f1) -- ssh-import-id $@; then
	    break
	  fi
	  sleep 5
	done
	systemctl stop import-ssh.timer
	systemctl disable import-ssh.timer
	rm -f "\$0"
	rm -f /etc/systemd/system/import-ssh.timer
	rm -f /etc/systemd/system/import-ssh.service
	rmdir --ignore-fail-on-non-empty "$(dirname "$SCRIPT")"
	EOF
  chmod 700 "$SCRIPT"

  cat <<- EOF > /etc/systemd/system/import-ssh.timer
		[Unit]
		Description=Import SSH keys using ssh-import-id
		[Timer]
		OnBootSec=1
		OnUnitActiveSec=10
		[Install]
		WantedBy=timers.target
	EOF

  cat <<- EOF > /etc/systemd/system/import-ssh.service
		[Unit]
		Description=Import SSH keys using ssh-import-id
		After=network-online.target userconfig.service
		[Service]
		Type=oneshot
		ExecStart=$SCRIPT
	EOF
  ln -f -s /etc/systemd/system/import-ssh.timer \
  /etc/systemd/system/timers.target.wants/import-ssh.timer
)

set_keymap () (
  if [ "$#" -ne 1 ]; then
    usage set_keymap
    exit 1
  fi
  raspi-config nonint do_configure_keyboard "$1"
)

set_timezone () (
  if [ "$#" -ne 1 ]; then
    usage set_timezone
    exit 1
  fi
  raspi-config nonint do_change_timezone "$1"
)

if [ "$#" -eq 0 ]; then
  echo "No command specified"
  usage
  exit 1
fi

command="$1"; shift
case "$command" in
  set_hostname|import_ssh_id|enable_ssh|set_wlan_country|set_wlan|set_keymap|set_timezone)
    "$command" "$@"
    ;;
  *)
    echo "Unsupported command: $command"
    usage
    exit 1
    ;;
esac
