#!/usr/bin/env bash
# Install the latest stable GitHub version of Bluetooth 2 USB. Handles installing submodules, too. 

# Temporarily disable history expansion
set +H

# ANSI escape codes for colored output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
# Reset to default color
NC='\033[0m'

colored_output() {
  local color_code="$1"
  local message="$2"
  local no_newline_flag="$3"
  local colored_message="${color_code}${message}${NC}"
  if [ "${no_newline_flag}" == "-n" ]; then
    echo -ne "${colored_message}"
  else
    echo -e "${colored_message}"
  fi
}

abort_install() {
  local message="$1"
  colored_output "${RED}" "Aborting installation. ${message}"
  exit 1
}

# Check for superuser privileges
if [[ $EUID -ne 0 ]]; then
    colored_output "${RED}" "This script must be run as root. Attempting to elevate privileges..."
    # Re-run the script as root
    exec sudo bash "$0" "$@"
fi

# Function to append text to a file if the text doesn't already exist in the file
append_if_not_exist() {
  local text="$1"
  local file="$2"
  local backup="${file}.bak"
  # Create a backup of the original file
  cp "${file}" "${backup}" || abort_install "Failed creating backup of ${file}."
  if ! grep -q "^${text}" "${file}"; then
    echo "${text}" >> "${file}" || abort_install "Failed writing to ${file}."
  fi
}

# Function to cleanup before exiting
cleanup() {
  # Re-enable history expansion
  set -H
}

main() {
  # Install prerequisites.
  colored_output "${GREEN}" "Installing bluetooth_2_usb prerequisites..."
  { apt-get update && apt-get install -y git python3 python3-venv python3-dev ; } || abort_install "Failed installing prerequisites."

  # Determine the current script's directory and the parent directory
  scripts_directory=$(dirname "$(readlink -f "$0")")
  base_directory=$(dirname "${scripts_directory}")
  cd "${base_directory}"

  # Capture the current user and group ownership 
  current_user=$(stat -c '%U' .) || abort_install "Failed retrieving current user ownership."
  current_group=$(stat -c '%G' .) || abort_install "Failed retrieving current group ownership."

  colored_output "${GREEN}" "Creating Python virtual environment \"${base_directory}/venv\"..."
  python3 -m venv venv || abort_install "Failed creating Python virtual environment."

  colored_output "${GREEN}" "Installing dependencies in venv..."
  venv/bin/pip3 install -r requirements.txt || abort_install "Failed installing dependencies."

  CONFIG_FILE="/boot/config.txt"

  # If /boot/config.txt starts with "DO NOT EDIT THIS FILE" or doesn't exist, 
  # then switch to using /boot/firmware/config.txt
  if grep -q '^DO NOT EDIT THIS FILE' "/boot/config.txt" 2> /dev/null || [ ! -f "/boot/config.txt" ]; then
    if [ -f "/boot/firmware/config.txt" ]; then
      colored_output "${GREEN}" "Using /boot/firmware/config.txt because /boot/config.txt is not editable or does not exist."
      CONFIG_FILE="/boot/firmware/config.txt"
    fi
  fi

  colored_output "${GREEN}" "Modifying system files..."

  # Make a backup before modifying
  cp "${CONFIG_FILE}" "${CONFIG_FILE}.bak"

  # 1. If there's no [all] section, append one with dtoverlay=dwc2
  if ! grep -q '^\[all\]' "${CONFIG_FILE}"; then
    cat <<EOF >> "${CONFIG_FILE}"

[all]
dtoverlay=dwc2
EOF
  else
    # 2. If [all] exists, check if dtoverlay=dwc2 is already there.
    #    If not, insert it right after the [all] line.
    awk -v overlay="dtoverlay=dwc2" '
    BEGIN { inAll=0; found=0 }
    {
      if ($0 ~ /^\[all\]/) { inAll=1; next }
      else if ($0 ~ /^\[.*\]/) { inAll=0 }
      if (inAll && index($0, overlay) == 1) { found=1 }
    }
    END { exit !found }
    ' "${CONFIG_FILE}" || sed -i '/^\[all\]/a dtoverlay=dwc2' "${CONFIG_FILE}"
  fi

  # Enable modules in /etc/modules
  append_if_not_exist "dwc2" "/etc/modules"
  append_if_not_exist "libcomposite" "/etc/modules"
  modprobe dwc2 || abort_install "Failed modprobe dwc2"
  modprobe libcomposite || abort_install "Failed modprobe libcomposite"


  # Before creating symlink in /usr/bin, check if /usr/bin/bluetooth_2_usb exists
  if [ ! -e "/usr/bin/bluetooth_2_usb" ]; then
    ln -s "${base_directory}/bluetooth_2_usb.sh" /usr/bin/bluetooth_2_usb || colored_output "${YELLOW}" "Failed creating symlink."
  fi

  # Before creating symlink for the systemd service, check if it already exists
  if [ ! -e "/etc/systemd/system/bluetooth_2_usb.service" ]; then
    ln -s "${base_directory}/bluetooth_2_usb.service" /etc/systemd/system/ || colored_output "${YELLOW}" "Failed creating symlink."
  fi

  # Enable service.
  systemctl enable bluetooth_2_usb.service || abort_install "Failed enabling service."
  systemctl start bluetooth_2_usb.service || abort_install "Failed starting service."

  # Restore ownership
  chown -R "${current_user}:${current_group}" "${base_directory}"

  version=$(/usr/bin/bluetooth_2_usb -v)
  if [[ $version == *"Bluetooth 2 USB"* ]]; then
    colored_output "${GREEN}" "Installation successful. Now running ${version}"
    colored_output "${YELLOW}" "A reboot is required."
  else
    colored_output "${RED}" "Installation failed. The version information could not be retrieved."
  fi
}

# Trap EXIT signal and call cleanup function
trap cleanup EXIT

log_dir="/var/log/bluetooth_2_usb"
if [ ! -d "${log_dir}" ]; then
    mkdir "${log_dir}" || colored_output "${YELLOW}" "Failed creating log dir."
fi

# Call the main function and pipe its output to tee
main 2>&1 | tee  "${log_dir}/install.log"
