#!/bin/sh
# Forces the installation of the TOL packages shipped with this .deb into the
# calling user's own package area.
#
# NOT normally needed. TOL does it by itself: the zips travel in
# bin/stdlib/DefaultPackages, and TolPackage::Client::Initialize installs from
# there, at startup, everything that is not in the catalogue yet. This script is
# for when that has to be forced -- repairing a package, or after deleting one by
# hand.
#
# Why the area is per user, and not somewhere under /usr: TOL has no system-wide
# package area. The area is TolAppDataPath + "TolPackage.<n>/", and TolAppDataPath is
# $HOME/.tol/ unless the TOLHOME environment variable says otherwise (see
# tol/bbasic/sys.cpp, Buil_TolAppData_). TOLHOME cannot be pointed at a
# read-only directory under /usr either, because TOL creates subdirectories
# inside it -- syslog, OIS, tests_results -- the first time it starts. So the
# .deb ships the zips and every user materialises their own area from them.
#
# Re-running this is safe: installing a package that is already there just
# overwrites it with the same content.
set -e

# The script finds its own root, so the .deb can be relocated without editing
# anything: it lives in <root>/bin, the zips in <root>/bin/stdlib/DefaultPackages,
# which is where the ENGINE looks at startup.
TOL_ROOT=$(cd "$(dirname "$0")/.." && pwd)
ZIPS=${TOL_PACKAGE_ZIPS:-$TOL_ROOT/bin/stdlib/DefaultPackages}
TOLSH=${TOLSH:-$TOL_ROOT/bin/tolsh}

if [ ! -d "$ZIPS" ]; then
  echo "tol-install-packages: no package directory at $ZIPS" >&2
  exit 1
fi
if [ ! -x "$TOLSH" ]; then
  echo "tol-install-packages: no usable tolsh at $TOLSH" >&2
  exit 1
fi

n=$(find "$ZIPS" -maxdepth 1 -name '*.zip' | wc -l)
if [ "$n" -eq 0 ]; then
  echo "tol-install-packages: no zips in $ZIPS" >&2
  exit 1
fi

script=$(mktemp /tmp/tol-install-packages.XXXXXX.tol)
trap 'rm -f "$script"' EXIT

# One single tolsh run for all the packages: starting the interpreter costs
# about a second, and doing it once per package would dominate the whole job.
{
  echo '#Require TolPkg;'
  echo 'Set _zips = SetOfText('
  find "$ZIPS" -maxdepth 1 -name '*.zip' | sort |
    awk 'NR>1 {printf ",\n"} {printf "  \"%s\"", $0} END {printf "\n"}'
  echo ');'
  # The Client lives under TolPackage, not under TolPkg: "TolPkg::Client" does
  # not resolve at all.
  echo 'Real _done = SetSum(EvalSet(_zips, Real(Text z) {'
  echo '  TolPackage::Client::InstallZip(z)'
  echo '}));'
  echo 'WriteLn("tol-install-packages: "+FormatReal(_done,"%g")+" installed");'
} > "$script"

echo "tol-install-packages: installing $n packages with $TOLSH"
"$TOLSH" -v "$script"
