#!/bin/sh

set -eu
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[0;33m"
NC="\033[0m"

prepare_hp_utils() {
  puavo-pkg install /usr/share/puavo-pkg/packages/hp-bios-utils.tar.gz
  export PATH="/opt/hp/hp-flash:${PATH}"
  hp_utils_dir='/opt/hp/hp-flash'
}

use_hp_utils() {
  prepare_hp_utils

  cat << EOF
> Running Bash for you, the current working directory is "${hp_utils_dir}".
> It has "hp-flash" and "hp-repsetup".
> PATH is $PATH
> Exit Bash when done.
EOF
  (cd "$hp_utils_dir" && bash)
}

check_hash() {
  providedhash="$(xmllint --xpath "string(/BIOS/Rel[starts-with(@Bin,\"$hp_select_bios\")]/@Sha384)" "$mainboard_sysid.xml")"
  calculatedhash=$(sha384sum "$hp_select_bios" | awk '{print $1}')

  if [ -n "$providedhash" ]; then
    echo "Cryptographic hash for the binary was found in the list. Comparing it now."
    if [ "$(printf "%s" "$calculatedhash" | grep -iP "^${providedhash}$")" ] ; then
      printf "${GREEN}The hash is a match, continuing.${NC}"
    else
      printf "${RED}The hash does NOT match, aborting.${NC}\n"
      printf "Calculated hash: %s\nProvided hash: %s\n" "$calculatedhash" "$providedhash"
      return 1
    fi
  else
    printf "${YELLOW}WARNING: No cryptographic hash found for the binary. Proceed with caution.${NC}"
  fi
}

flash() {
  prepare_hp_utils

  param=""
  version=""
  mainboard_sysid=$(dmidecode -s baseboard-product-name)
  hp_ftp_url="https://ftp.ext.hp.com/pub/pcbios"

  (cd "$hp_utils_dir" && \
    wget "$hp_ftp_url/$mainboard_sysid/$mainboard_sysid.xml" -O "$mainboard_sysid.xml" && \
    if [ $# -le 2 ]; then
      for i in "${@}"; do
        if [ "$i" = "-y" ]; then
          param="$i"
        elif [ "$i" = "latest" ]; then
          version="$(xmllint --xpath "string(/BIOS/Rel/@Bin)" "$mainboard_sysid.xml")"
        elif [ "$i" != "-y" -a "$i" != "latest" ]; then
          echo "Invalid parameters!"
          echo "Accepted parameters are: '-y' and 'latest'"
          return 1
        fi
      done
    fi

    hp_select_bios="$(xmllint --xpath "(/BIOS/Rel/@Bin)" "$mainboard_sysid.xml" | cut -d '"' -f 2 \
     | fzf --query "$version" --select-1 --height=9 --layout=reverse-list --color=bg+:#FFFFFF,fg+:#000000
    )" && wget "$hp_ftp_url/$mainboard_sysid/$hp_select_bios" -O "$hp_select_bios" && \
    check_hash && hp-flash "$hp_select_bios" $param)
}

import_config() {
  prepare_hp_utils

  config="$1"
  baseurl_git="https://raw.githubusercontent.com/opinsys/opinsys-host-configurations/main/HP"

  ### Create log file solely for gathering errors from curl.
  ### If it already exists, just move it out of the way so we can read it if needed.
  errlogfile="/tmp/puavo-bios-config-curl.log"

  if [ -f "$errlogfile" ]; then
    mv "$errlogfile" "/tmp/puavo-bios-config-curl.log.old"
  fi

  (cd "$hp_utils_dir" && curl -O --silent --show-error \
   --url "$baseurl_git/$config" \
   --write-out "$config") 2>> "$errlogfile" || true

  if [ ! -f "$hp_utils_dir/$config" ] && [ "$(grep -c . "$errlogfile")" -gt 0 ]; then
    echo "Could not find config $config in $hp_utils_dir. Config was not imported!!"
    echo "Error log has entries, see $errlogfile."
  else
    (cd "$hp_utils_dir" && hp-repsetup -s "$config")
    echo "\nSelected config $config should now be set.\nPlease check the output above to be sure.\n\n"
  fi

  echo "Returning to puavo-bios-config menu.\n"
}

ask_choice() {
  choices=$(cat <<'EOF'
Flash latest BIOS version (HP)
Flash select BIOS version (HP)
Import Student laptop BIOS Config
Import Student laptop BIOS Config (UEFI)
Import USB Stick factory BIOS Config
Import USB Stick factory BIOS Config (UEFI)
use HP BIOS utilities
exit
EOF
)
  printf "%s" "$choices" | fzf --height=10 --layout=reverse-list --color=bg+:#FFFFFF,fg+:#000000
}

printf "\n"
printf ">>> Welcome to puavo-bios-config!\n"
printf ">>> What do you want to do?\n\n"

if [ $# -ge 1 ] && [ $# -le 3 ]; then
  chosen="$1"
  option2="${2:-}"
  option3="${3:-}"
  eval $chosen $option2 $option3
else
  while chosen=$(ask_choice); do
    printf ">> You chose '${chosen}'\n"

    case "$chosen" in
      exit)
        exit 0
        ;;
      'Flash latest BIOS version (HP)')
        flash latest
        sleep 3
        ;;
      'Flash select BIOS version (HP)')
        flash
        sleep 3
        ;;
      'Import Student laptop BIOS Config')
        import_config HpSetup-student-laptop.txt
        sleep 3
        ;;
      'Import Student laptop BIOS Config (UEFI)')
        import_config HpSetup-student-laptop-uefi.txt
        sleep 3
        ;;
      'Import USB Stick factory BIOS Config')
        import_config HpSetup-usb-factory.txt
        sleep 3
        ;;
      'Import USB Stick factory BIOS Config (UEFI)')
        import_config HpSetup-usb-factory-uefi.txt
        sleep 3
        ;;
      'use HP BIOS utilities')
        use_hp_utils
        ;;
    esac
  done
fi
