#!/bin/bash

## Copyright (C) 2026 - 2026 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -o errexit
set -o nounset
set -o errtrace
set -o pipefail

export LC_ALL='C'

# shellcheck source=../libexec/helper-scripts/log_run_die.sh
source /usr/libexec/helper-scripts/log_run_die.sh

# shellcheck source=../libexec/helper-scripts/as_root.sh
source /usr/libexec/helper-scripts/as_root.sh

# shellcheck source=../libexec/helper-scripts/has.sh
source /usr/libexec/helper-scripts/has.sh

rebuild_dkms_modules() {
  local dkms_mod_status_item dkms_mod_name dkms_mod_kernel dkms_mod_status \
    dkms_build_count

  as_root

  if ! has dkms; then
    log error "Missing required tool: 'dkms' (Dynamic Kernel Module Support)."
    log error "Without it, DKMS modules cannot be built and installed. Please install 'dkms' and run this tool again."
    return 1
  fi

  log notice 'Rebuilding DKMS modules...'

  dkms_build_count='0'
  while IFS= read -r dkms_mod_status_item; do
    if ! [[ "${dkms_mod_status_item}" \
      =~ ^([^,]*),\ ([^,]*),\ [^:]*:\ (.*)$ ]]; then
      log warning "Failed to parse DKMS module status line '${dkms_mod_status_item}'! Ignoring."
      continue
    fi
    dkms_mod_name="${BASH_REMATCH[1]}"
    dkms_mod_kernel="${BASH_REMATCH[2]}"
    dkms_mod_status="${BASH_REMATCH[3]}"
    log notice "DKMS module status info: name: '${dkms_mod_name}', kernel: '${dkms_mod_kernel}', status: '${dkms_mod_status}'"

    if [[ "${dkms_mod_status}" != installed* ]]; then
      log notice "DKMS module '${dkms_mod_name}' not installed for kernel '${dkms_mod_kernel}', skipping, ok."
      continue
    fi
    log notice "Rebuilding DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}'..."
    if ! log_run notice dkms build "${dkms_mod_name}" -k "${dkms_mod_kernel}" --force; then
      log warning "DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}' failed to build! Skipping."
      continue
    fi
    log notice "Successfully rebuilt DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}'."
    log notice "Installing DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}'..."
    if ! log_run notice dkms install "${dkms_mod_name}" -k "${dkms_mod_kernel}" --force; then
      log warning "DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}' failed to install! Skipping."
      continue
    fi
    log notice "Successfully installed DKMS module '${dkms_mod_name}' for kernel '${dkms_mod_kernel}'."
    (( dkms_build_count++ )) || true
  done < <(dkms status)

  if [ "${dkms_build_count}" = '0' ]; then
    log notice 'No DKMS modules to rebuild, ok.'
  else
    log notice 'Done rebuilding DKMS modules.'
  fi
}

rebuild_dkms_modules
