#!/bin/bash

#set -x # Set to help debug

show_usage()
{
   i=0;        usage[$i]="Usage: $0 [-p<path>] [-fsad] [-u<user>]"
   i=$((i+1)); usage[$i]="Where:"
   i=$((i+1)); usage[$i]="p \t= Use specific path instead of current directory"
   i=$((i+1)); usage[$i]="f \t= Use patched NCURSES version, thread-safe is default"
   i=$((i+1)); usage[$i]="s \t= Set system-wide environment instead of just current user"
   i=$((i+1)); usage[$i]="a \t= Force setup of /etc/apt/sources.list and restore when done (requires sudo)"
   i=$((i+1)); usage[$i]="u \t= Update this user's .bashrc instead of current user. Typically for when run under sudo"
   i=$((i+1)); usage[$i]="d \t= Dry run. Just show commands."

   for i in "${usage[@]}"; do
      echo -e $i
   done
}

# Defaults
homedir=$HOME

# process options
while getopts "h?p:fsadu:" opt; do
   case $opt in
      p  ) target_dir=$OPTARG ;;
      f  ) patch_ncurses=true ;;
      s  ) system=true ;;
      a  ) handle_apt=true ;;
      u  ) user=$OPTARG
           homedir="/home/${OPTARG}" ;;
      d  ) dry="echo" ;;
      h | \
      \? ) show_usage && exit 1
           exit 1 ;;
   esac
done
shift $(($OPTIND - 1))

# remove previous install, if any
$dry rm -rf ncurses*

# Learn the OS so that we can handle non-Ubuntu "kind of" gracefully
. /etc/os-release
codename="$VERSION_CODENAME"
case "$codename" in
   ulyana|uma|una)                 release="focal" ;;
   vanessa|vera|victoria|virginia) release="jammy" ;;
   xia)                            release="noble" ;;
   *)                              release="$codename" ;;
esac
if [ "$ID" = "rhel" ]; then
   is_rhel=true
fi

# get up to date version
if [[ "$handle_apt" == "true" ]]; then
   if [[ -f "/etc/apt/sources.list.d/ubuntu.sources" ]]; then
      $dry sudo cp /etc/apt/sources.list.d/ubuntu.sources /tmp
      $dry sudo sed -i '/^Types: deb$/a Types: deb-src' /etc/apt/sources.list.d/ubuntu.sources
   elif [[ -f "/etc/apt/sources.list.d/official-package-repositories.list" ]]; then
      $dry sudo cp /etc/apt/sources.list.d/official-package-repositories.list /tmp
      $dry sudo grep -q '^deb-src' /etc/apt/sources.list.d/official-package-repositories.list || \
      $dry sudo sed -e 's|^deb |deb-src |' /etc/apt/sources.list.d/official-package-repositories.list >> /etc/apt/sources.list.d/deb-src.list
   else
      $dry sudo echo "deb-src http://archive.ubuntu.com/ubuntu $release main restricted universe multiverse" >> /etc/apt/sources.list
   fi
   $dry sudo apt-get update
fi

# install ncurses source code for this version
if [ -z "$is_rhel" ]; then
   $dry apt-get -q -y source ncurses
else
   $dry yum install ncurses-devel
fi

if [[ "$handle_apt" == "true" ]]; then
   if [[ -f "/etc/apt/sources.list.d/ubuntu.sources" ]]; then
      $dry sudo mv /tmp/ubuntu.sources /etc/apt/sources.list.d/
   else
      $dry sudo mv /tmp/sources.list /etc/apt/
   fi
   $dry sudo apt-get update
fi

# check if sources obtained
if [ $? -ne 0 ] && [ -z "$dry" ]
then
   echo "+------------------------------------------------------------------------------+"
   echo "|                  Unable to get NCURSES source tree!                          |"
   echo "|       Check the available packages list in /etc/apt/sources.list.            |"
   echo "+------------------------------------------------------------------------------+"
   exit
fi

# patching the source files
$dry pushd ncurses-6.* > /dev/null
if [[ "$patch_ncurses" == "true" ]]; then
#   $dry wget https://proj.goldencode.com/downloads/ncurses/ncurses_curses_h_in_v6.4+20240113.patch
#   $dry wget https://proj.goldencode.com/downloads/ncurses/ncurses_lib_getch_c_v6.4+20240113.patch
   $dry patch include/curses.h.in      ../libncurses_curses_h_in_v6.4+20240113.patch
   $dry patch ncurses/base/lib_getch.c ../libncurses_lib_getch_c_v6.4+20240113.patch
fi

# configure and build object libraries
if [[ "$patch_ncurses" == "true" ]]; then
   $dry ./configure --with-termlib CFLAGS='-fPIC -O2' --with-abi-version=6 --disable-widec
else
   $dry ./configure --with-termlib CFLAGS='-fPIC -O2' --with-abi-version=6 --with-pthread --enable-pthreads-eintr --disable-widec
fi
$dry make

# make valid reference to updated ncurses.h
$dry cd include
$dry ln -s curses.h ncurses.h
$dry cd ..

if [[ "$patch_ncurses" == "true" ]]; then
   echo "+------------------------------------------------------------------------------+"
   echo "|                 Patched NCURSES libraries update completed.                  |"
else
   echo "+------------------------------------------------------------------------------+"
   echo "|               Thread-safe NCURSES libraries build completed.                 |"
fi

# Position minimal files if path is specified
if [[ ! -z "$target_dir" ]]; then
   $dry mkdir -p $target_dir
   $dry cp -r include $target_dir
   $dry cp -r lib $target_dir
   $dry cd $target_dir
   [ -n "$user" ] && $dry chown -R $user:$user $target_dir
fi

# Set up environment variable(s) if they are not set already
env_update=""; sudo_update=""
if [ -z "$NCURSES_FWD_STATIC" ]; then
   env_update+="export NCURSES_FWD_STATIC=\"$PWD\""$'\n'
   sudo_update+="Defaults env_keep += NCURSES_FWD_STATIC"$'\n'
fi
if [ -z "$NCURSES_FWD_PTHREADS" ] && [ "$patch_ncurses" != true ]; then
   env_update+="export NCURSES_FWD_PTHREADS=true"$'\n'
   sudo_update+="Defaults env_keep += NCURSES_FWD_PTHREADS"$'\n'
fi
if [ ."$env_update". != ".." ]; then
   if [[ "$system" == true ]]; then
      rc_filename='/etc/profile.d/10-ncurses.sh'
      msg="|         The environment has been changed! Reboot to activate changes         |"
      # Ensure we are making the only entry in the profile.d script
      [ -f "$rc_filename" ] && $dry rm -f $rc_filename 
      [ -z "$dry" ] && echo -n "$sudo_update" > /etc/sudoers.d/10-ncurses
      mode="644"
   else
      rc_filename="${homedir}/.bashrc"
      msg="|   The .bashrc has been changed! Please open new console to activate setup!   |"
   fi
   if [[ -z "$dry" ]]; then
      echo '' >> $rc_filename
      if [[ "$patch_ncurses" == true ]]; then
         echo '# set up patched NCURSES root location' >> $rc_filename
      else
         if [ -z "$NCURSES_FWD_STATIC" ]; then
            echo '# set up thread-safe NCURSES root location' >> $rc_filename
         fi
         if [ -z "$NCURSES_FWD_PTHREADS" ]; then
            echo '# and set up thread-safe NCURSES_FWD_PTHREADS variable' >> $rc_filename
         fi
      fi
      echo -n "$env_update" >> $rc_filename 
      if [[ "$system" == true ]]; then
         chmod $mode $rc_filename
      fi
   fi
   echo "|   ---------------------------   WARNING ! --------------------------------   |"
   echo "$msg"
   echo "|   ---------------------------   WARNING ! --------------------------------   |"
fi

echo "|              Please do FULL FWD rebuild to activate the changes.             |"
echo "+------------------------------------------------------------------------------+"

# back to the starting directory
$dry popd > /dev/null
