#!/bin/sh

set -e

if [ "$(whoami)" != "root" ]; then
  echo "Error: you must be root or use sudo to execute this command"
  exit 1
fi

. /usr/share/debconf/confmodule
db_version 2.0

usage() {
  echo "$0 called with unknown command: $1"
  echo "Usage: $0 [enable|disable]"
  exit 1
}

is_x_running() {
  if [ -n "$(find /tmp/.X11-unix -type s)" ]; then
	return 0
  else
	return 1
  fi
}

print_xrunning_note() {
  if is_x_running; then
    echo ""
    echo "Warning: your X configuration has been succesfully changed."
    echo "In order to take full advantage of the changes, X needs to"
    echo "be restarted."
    echo ""
  fi 
}

print_xconfig_note() {
  echo ""
  echo "Error: your X configuration has been altered."
  echo "This script cannot proceed automatically. If you believe that this"
  echo "not correct, you can update the md5sum entry executing the following"
  echo "command:"
  echo "md5sum /etc/X11/${CONFIGFILE} | sudo tee /var/lib/x11/${CONFIGFILE}.md5sum"
  echo "otherwise edit manually /etc/X11/${CONFIGFILE} to change the Driver section"
  case "$1" in
    enable)
      echo "from nv to nvidia."
    ;;
    disable)
      echo "from nvidia to nv."
    ;;
    *)
      echo "this should never happen!"
    ;;
  esac
  exit 1
}

print_missing_files() {
  echo ""
  echo "Error: /etc/X11/${CONFIGFILE} or /var/lib/x11/${CONFIGFILE}.md5sum"
  echo "are missing from your system. Please be sure that your xserver package is"
  echo "installed correctly."
  echo ""
  exit 1
}

check_config() {
  if [ -e /etc/X11/${CONFIGFILE} ] && [ -e /var/lib/x11/${CONFIGFILE}.md5sum ]; then
    if [ "$(md5sum /etc/X11/${CONFIGFILE})" = "$(cat /var/lib/x11/${CONFIGFILE}.md5sum)" ]; then
      return 0
    else
      return 1
    fi
  else
    print_missing_files
  fi
}

do_debconf() {
  case $1 in
    enable)
      db_set ${SERVER}/config/device/driver nvidia
    ;;
    disable)
      db_set ${SERVER}/config/device/driver nv
    ;;
    *)
      echo "this should NEVER happen!"
      exit 1
    ;;
  esac
}

backup_config() {
  mkdir -p /var/backups/xorg
  data=$(LC_ALL=C date +%F-%H:%M:%S)
  cp /etc/X11/$CONFIGFILE /var/backups/xorg/${CONFIGFILE}.$data
  echo ""
  echo "A backup of ${CONFIGFILE} has been stored as:"
  echo "/var/backups/${CONFIGFILE}.$data."
  echo "If the new configuration will not work you will be able to"
  echo "revert the changes simply using this command:"
  echo "cp /var/backups/xorg/${CONFIGFILE}.$data /etc/X11/${CONFIGFILE}"
  echo ""
}

write_x_config() {
  backup_config
  rm -f /etc/X11/${CONFIGFILE}
  dexconf -o /etc/X11/${CONFIGFILE}
  md5sum /etc/X11/${CONFIGFILE} > /var/lib/x11/${CONFIGFILE}.md5sum
}

manage_x_driver() {
  if check_config; then
    do_debconf $1
    write_x_config
  else
    print_xconfig_note $1
  fi
  print_xrunning_note
}

manage_kernel_driver() {
  tmpfile=$(tempfile)
  chmod 644 $tmpfile
  case "$1" in
    enable)
      modprobe -i nvidia > /dev/null 2>&1
      if [ -z "$(cat /proc/modules | awk '{print $1}' | grep ^nvidia$)" ]; then
        echo "Error: unable to load nvidia kernel driver! Be sure to have installed"
        echo "the nvidia driver for your running kernel."
        exit 1
      fi
      #if ! grep -Eq '^nvidia$' /etc/modules && ! grep -Eq '^# nvidia$' /etc/modules; then
      #  echo nvidia >> /etc/modules
      #elif grep -Eq '^# nvidia$' /etc/modules; then
      #  cat /etc/modules | sed -e 's/^# nvidia$/nvidia/g' > $tmpfile
      #  mv $tmpfile /etc/modules
      #fi
    ;;
    disable)
      if grep -Eq '^nvidia$' /etc/modules && ! grep -Eq '# nvidia$' /etc/modules; then
        cat /etc/modules | sed -e 's/^nvidia/# nvidia/g' > $tmpfile
        mv $tmpfile /etc/modules
        set +e
        rmmod nvidia > /dev/null 2>&1
        set -e
      fi
    ;;
    *)
      echo "this should NEVER happen!"
      exit 1
    ;;
  esac
  rm -f $tmpfile
}

if [ -e /etc/X11/xorg.conf ]; then
	CONFIGFILE="xorg.conf"
	SERVER="xserver-xorg"
else
	CONFIGFILE="XF86Config-4"
	SERVER="xserver-xfree86"
fi

case "$1" in
  enable|disable)
    manage_kernel_driver $1
    manage_x_driver $1
  ;;
  *)
    usage
  ;;
esac

exit 0
