#!/bin/bash -

# run as user

###############################################################################
# switchTexlive.sh — switch a TeX Live release already installed
#
# SYNOPSIS
#   source switchTexlive.sh <YEAR>
#
# DESCRIPTION
#   This script switches to given texlive release by adapting the user PATH,
#   provided texlive is installed for the current platform 
#   in particular for the current user the paths are set accordingly 
#   and it is a classical parallel texlive installation. 
#   Since switching consists in adapting the path, 
#   this script must be invoked by user (not by root) via `source`. 
#
#   To be a classical parallel texlive installation, `tlmgr` must be on the path, 
#   i.e. the path must contain the folder containing `tlmgr` and this has the form 
#
#       <ROOT>/<YEAR'>/bin/<platform>
#
#   where 
#      - <platform> is normally a combination of hardware and operating sytem, like `windows` or `x86_64-linux`
#      - <YEAR'> is the year of the release currently installed. 
#      - <ROOT> is by default (see https://www.tug.org/texlive/doc/texlive-en/texlive-en.html, Section 3.2.3)
#
#       /usr/local/texlive   (unixoid OS)
#       c:/texlive           (windows)
#
#   The above path must be removed from the PATH and 
#
#       <ROOT>/<YEAR>/bin/<platform>
#
#   must be added as first element, but this is done only, if that folder exists. 
#
#   Please use `instTexlive.sh` to install a missing release or plattform and to add further packages. 
#
#   Note that the package manager `tlmgr` is among the executables and so the following is available to the user: 
#   - `tlmgr --list` lists the packages and marks the installed ones by `i`. 
#   - `tlmgr update --list` lists the packages for which an update is available. 
#   - `tlmgr info <package>` lists various pieces of information for <package>; see `tlmgr bug <package>`
#   - `tlmgr bug <package>` lists bug contact for <package>
#
# REQUIREMENTS
#   - classical installation of TeX Live with `tlmgr` in proper place also for the requested year. 
#   - Must not be executed as root.
#
# ACTIONS PERFORMED
#   PATH cleanup and activation of the selected version fitting the current platform.
#
# EXIT CODES
#   0  success
#   1  problem with invocation
#      - invoker may be all but root, 
#      - invalid arguments (exactly one argument: release year shall be given by 4 digits)
#      - `tlmgr` not found 
#   2  problem with current installation 
#      - `tlmgr` not found: seems no TeX Live installed, at least no classical one. 
#      - Binaries like `tlmgr` must be in a folder with path <ROOT>/<YEAR>/bin/<platform>
#        so 4 digit <YEAR> is mandatory and so is `bin`. 
#   3  release <YEAR> is not installed  (invoke `instTexlive.sh <YEAR>` before)
#   4  current platform (given by architecture and os) not installed (maybe not supported) 
#      although the given release is installed as such. 
#
# EXAMPLES
#   switch to TeX Live 2025:
#       source ./actTexlive.sh 2025
#
# SEE ALSO
#   The sibling script is `instTexlive.sh` for installation. 
#
# AUTHOR
#   Your Name <ernst.reissner@simuline.eu>
#
###############################################################################


# messaging 
error() { printf "\e[91m✖ ERROR: %s\e[0m\n" "$1" >&2; }
warn()  { printf "\e[93m⚠ WARN: %s\e[0m\n" "$1"; }
info()  { printf "\e[94mℹ INFO: %s\e[0m\n" "$1"; }
succ()  { printf "\e[92m✔ DONE: %s\e[0m\n" "$1"; }

# check root and parameter 
#[ "$EUID" -ne 0 ] || { error "Please run as user, not as root."; return 1; }
[ "$#" -eq 1 ] || { error "Usage: $0 <year in 4 digits>."; return 1; }
YEAR="$1"
[[ "$YEAR" =~ ^[0-9]{4}$ ]] || { error "Invalid argument: year must be exactly 4 digits."; return 1; }

# Determine ROOT folder for all texlive installations 
TLMGR_PATH=$(command -v tlmgr) || { error "Expected 'tlmgr' but not found; classical TeX Live installed?"; return 2; }
# Here, TLMGR_PATH=<ROOT/<YEAR>/bin/<platform>/tlmgr is expected 
BIN_DIR=$(dirname "$TLMGR_PATH")                     # <ROOT>/<YEAR>/bin/<platform>
TL_PLATFORM=$(basename "$BIN_DIR")                   # <platform> without check 
BIN_LIT=$(basename "$(dirname "$BIN_DIR")")
[ "$BIN_LIT" = "bin" ] || { error "Found 'tlmgr' not in ./bin/.../."; return 2; }
YEAR_DIR=$(dirname "$(dirname "$BIN_DIR")")
YEAR_ORG=$(basename "$YEAR_DIR")
[[ "$YEAR_ORG" =~ ^[0-9]{4}$ ]] || { error "Expected current texlive in folder <year> with exactly 4 digits; found $YEAR_ORG."; return 2; }
ROOT=$(dirname "$YEAR_DIR") # <ROOT>

# each release in the folder of its year 
INSTALL_DIR="$ROOT/$YEAR"
# The subfolder of the installation with the binaries for the given architecture 
BIN_DIR="$INSTALL_DIR/bin/$TL_PLATFORM"
# Here, BIN_DIR is the new one overwriting the original one 

[ -d "$INSTALL_DIR" ] || { error "No switch: Texlive not (properly) installed for year $YEAR."; return 3; }
[ -d "$BIN_DIR" ] || { error "No switch: Texlive $YEAR is not installed for current platform $TL_PLATFORM."; return 3; }

info "switching to path including $BIN_DIR..."
# switch the path to $YEAR
OLD_IFS="$IFS"
IFS=":"
read -ra ADDR <<< "$PATH"
NEW_PATH="$BIN_DIR"
for p in "${ADDR[@]}"; do
  # match else append 
  [[ "$p" =~ ^$ROOT ]] || NEW_PATH="$NEW_PATH:$p"
done
IFS="$OLD_IFS"

export PATH="$NEW_PATH"
info "switching done"

