#!/bin/bash
#
## @file		ocpkg
## @copyright		OpenCog Foundation (2012,2013,2014,2015)
## @author		David Hart <dhart@opencog.org>
## @section DESCRIPTION	A script to download, build, test, install and package OpenCog
## @section LICENSE	Permission to copy and modify is granted under the GPL
## @section REQUIREMENT	Ubuntu Linux 14.04 "Trusty Tahr". See opencog/ocpkg repo for 12.04 version
## @section SEEALSO	Dockerfile - compile and run OpenCog in a Linux container

# This bash script is organized in sections
# SECTION 1. Global variable setting
# SECTION 2. Command line option handling
# SECTION 3. Error handling & cleanup
# SECTION 4. Function definitions
# SECTION 5. Main program

# Notes
# 5 minute LiveCD creation is possible with a minimum of 4GB RAM, 4GB SWAP, and /tmp on 4GB tmpfs
# test CD/DVD images using:
#   testdrive -u OpenCogLive.iso
#   kvm -cdrom OpenCogLive.iso -boot d -m 2048

# To do
# Debian/Ubuntu packaging abilities http://developer.ubuntu.com/packaging/html/
# incremental builds
# manifest rebuild to LiveCD/DVD

# trap errors
set -e

# SECTION 1: GLOBAL VARIABLES

declare -A PACKAGE_DESCRIPTION=(
  [local]="Local install with no packaging (default)"
   [demo]="LiveCD  ISO image ~700MB with OpenCog Demo (auto-starting)"
    [min]="LiveCD  ISO image ~700MB with OpenCog Server"
    [dev]="LiveDVD ISO image ~900MB with OpenCog Developement Environment"
    [kvm]="TBD Ubuntu KVM image with OpenCog Server"
 [demovm]="TBD Ubuntu VirtualBox image with OpenCog Unity3D proxy for demo"
   [debs]="TBD Ubuntu packages (deb files)"
  [docker]="TBD Docker Images"
)

PATH_PREFIX=/usr/local
CURRENT_DIR=$(pwd)
SOURCE_DIR=""
BUILD_DIR=""

if [ "$USER" == "root" ] ; then
 HOST_SOURCE_BRANCH=$PATH_PREFIX/src/opencog
 HOST_BUILD_DIR=/tmp/opencog_build
else
 HOST_SOURCE_BRANCH=$CURRENT_DIR/opencog/src
 HOST_BUILD_DIR=$CURRENT_DIR/opencog/build
fi

SLEEP_TIME=0

OUTPUT_ISO_NAME=OpenCogLive.iso
OUTPUT_ISO_LOCATION=$CURRENT_DIR

DEFAULT_PACKAGE_TYPE=local
DEFAULT_ADD_REPOSITORIES=true
DEFAULT_INSTALL_DEPENDENCIES=true
DEFAULT_UPDATE_OPENCOG=true
DEFAULT_BUILD_OPENCOG=false
DEFAULT_TEST_OPENCOG=false

UBUNTU_ISO=ubuntu-20.04.3-desktop-amd64.iso
UBUNTU_URL=http://releases.ubuntu.com/20.04/
UBUNTU_MD5SUM=5fdebc435ded46ae99136ca875afc6f05bde217be7dd018e1841924f71db46b5
UBUNTU_ISO_IMAGE=$CURRENT_DIR/$UBUNTU_ISO #default location

SELF_NAME=$(basename $0)
TOOL_NAME=octool

GUILEVERSION=3.0.10

PROCESSORS=$(grep "^processor" /proc/cpuinfo | wc -l)
MAKE_JOBS=$(($PROCESSORS+0))

SQUASHFS_OPTIONS="-noDataCompression -noappend" #faster
SQUASHFS_OPTIONS="-noappend"

LIVE_SOURCE_BRANCH=$HOST_SOURCE_BRANCH
LIVE_BUILD_DIR=$HOST_BUILD_DIR

VERBOSE="-v"				#for mount, umount, rm, etc.
#QUIET="-qq" 				#for apt-get

LIVE_DESKTOP_SOURCE="OpenCog Source Code"

REPOSITORIES=""
#		ppa:opencog-dev/ppa \
#		opencog-dev: cxxtest
#		gandelman: python-flask-restful
#       ppa:chris-lea/zeromq \
#		ppa:chris-lea/python-flask \
#       ppa:chris-lea/python-itsdangerous \
#       ppa:chris-lea/python-simplejson \
#       ppa:gandelman-a/test-catalog \

PACKAGES_TOOLS="
		squashfs-tools \
		genisoimage \
		"
		#aria2 \
		#qemu-kvm \
		#testdrive \

PACKAGES_FETCH="
		git \
		curl \
		wget \
			"
		#bzr-rewrite \

PACKAGES_ADMIN="
		apt-rdepends \
		synaptic \
		gdebi \
		epiphany-browser \
		"

# The opencv-dev package is needed for vision processing. Unfortunately
# it sucks in vast numbers of junk packages as depdencies, including
# parts of X11, libgtk-3-common, ubuntu-mono, unixodbc-common, libtk8.6
# and more. Sidelining this one package could reduce a lot of cruft.
#
# libpq-dev is needed by the postgres storage node.
# nlohmann-json3-dev is needed by the cogserver.
PACKAGES_BUILD=" build-essential \
		cmake \
		rlwrap \
		binutils-dev \
		libiberty-dev \
		libltdl-dev \
		libbz2-dev \
		libboost-date-time-dev \
		libboost-filesystem-dev \
		libboost-math-dev \
		libboost-program-options-dev \
		libboost-regex-dev \
		libboost-serialization-dev \
		libboost-thread-dev \
		libboost-system-dev \
		libboost-random-dev \
		libedit-dev \
		libpcre2-dev \
		libpq-dev \
		uuid-dev \
		libssl-dev \
		ccache \
		cxxtest \
		libgsasl-dev \
		libldap2-dev \
		krb5-multidev \
		gperf \
		libatomic-ops-dev \
		libgmp-dev \
		libffi-dev \
		libreadline-dev \
		libunistring-dev \
		m4 \
		autoconf-archive \
		autoconf automake autopoint \
		libtool \
		swig \
		flex \
		librocksdb-dev \
		libopencv-dev \
		nlohmann-json3-dev \
		less \
		vim \
		"

# AtomSpace OCaML no longer builds in Ubuntu 22.04, and so disable here,
# until it is fixed.
		#ocaml \
		#ocaml-findlib \

PACKAGES_RUNTIME="
		postgresql-client \
		netcat-openbsd \
		"

PACKAGES_DOC="
		ubuntu-docs \
		#libglib2.0-doc \
		#libpango1.0-doc \
		#libgtk-3-doc \
		texlive-latex-base-doc \
		python-doc \
		devhelp-common \
		texlive-doc-base \
		doxygen \
 		dot2tex \
		"

PACKAGES_REMOVE="
		ubuntu-desktop \
		example-content \
		software-center \
		app-install-data \
		locales \
		python-twisted-core \
		ubiquity \
		rhythmbox \
		rhythmbox-data \
		empathy \
		empathy-common \
		libtelepathy-glib0 \
		firefox \
		thunderbird \
		libreoffice-core \
		evolution-data-server \
		gnome-games-common \
		gnome-games-data \
		aisleriot \
		deja-dup \
		gwibber \
		oneconf \
		shotwell \
		ubuntuone-client \
		python-ubuntuone-client \
		gnome-orca \
		libgweather-common \
		simple-scan \
		sane-utils \
		printer-driver-hpcups \
		printer-driver-hpijs \
		hplip \
		hplip-data \
		libgutenprint2 \
		foo2zjs \
		colord \
		libsane \
		samba-common \
		gnome-user-guide \
		ure \
		smbclient \
		indicator-messages \
		ubuntuone-client-gnome \
		geoip-database \
		libopencc1 \
		fonts-nanum \
		ttf-indic-fonts-core \
		ttf-wqy-microhei \
		fonts-takao-pgothic \
		libpurple0 \
		brltty \
		liblouis-data \
		"
		#ubuntu-wallpapers \
		#this stuff is for Unity 2D, but Ubuntu fails to login without it
		#libqtgui4 \
		#libqt4-core \
		#libqt4-xmlpatterns \
		#libwebkitgtk-3.0-0 \
		#language-pack-pt-base \
		#language-pack-es-base \
		#language-pack-xh-base \
		#language-pack-zh-hans \
		#language-pack-de-base \
		#language-pack-fr-base \
		#language-pack-ca-base \
		#language-pack-el-base \
		#language-pack-sv-base \
		#language-pack-ru-base \
		#language-pack-gnome-zh-hans-base \
		#language-pack-kde-zh-hans-base \
		# NOTES
		# apps listed first, then libraries that they depend upon which will
		#	also uninstall other stuff
		#	ubiquity - graphical Ubuntu installer that runs on boot
		#  23MB app-install-data (ubuntu software center)
		#  22MB ubuntu-docs (desktop docs)
		#  44MB thunderbird
		#  26MB amarok
		# 200MB libreoffice
		#  45MB smbclient

# Below is a list of packages that will be *removed* when building
# the demo and minimal packages. I dunno, I suspect many of these
# will fail, because they do not exist any more...
PACKAGES_EXDEV="
		autoconf automake autotools-dev \
		blt \
		comerr-dev \
		dpkg-dev \
		emacsen-common \
		fakeroot \
		gettext \
		gdb \
		g++ \
		gcc \
		krb5-multidev \
		libc6-dev \
		libdpkg-perl \
		libgcrypt11-dev \
		libgnutls-dev \
		libgpg-error-dev \
		libgssrpc4 \
		libidn11-dev \
		libalgorithm-diff-perl \
		libalgorithm-diff-xs-perl \
		libalgorithm-merge-perl \
		libkadm5clnt-mit8 \
		libkadm5srv-mit8 \
		libkrb5-dev \
		libldap2-dev \
		libltdl-dev \
		libstdc++-dev \
		libtasn1-3-dev \
		libtimedate-perl \
		libtool \
		libxss1 \
		make \
		manpages-dev \
		m4 \
		patch \
		ttf-lyx \
		zlib1g-dev \
		python-bzrlib \
		linux-headers-generic \
		# libcpprest \
		# libzmq3-dev \
		# libsdl-gfx1.2-dev \
		# tcl-dev \
		# tcsh \
		# libprotoc-dev \
		# protobuf-compiler \
		# wordnet \
		# wordnet-dev \
		# wordnet-sense-index \
		# liblua5.1-0-dev \
		# libxmlrpc-c3-dev \
		# python-flask \
		# python-flask-restful \
		# libglade2-0 \
		# python-glade2 \
		# python-tk \
		# tcl8.5 \
		# tk8.5 \
		"

# SECTION 2: Command line option handling

usage() {
if [ "$SELF_NAME" == "$TOOL_NAME" ] ; then
  echo "Usage: $SELF_NAME OPTION"
  echo " -r Add software repositories"
  echo " -d Install base/system build dependencies"
  echo " -p Install python build dependencies"
  echo " -s Install haskell build dependencies in user space. Don't use sudo"
  echo " -i Install build-job artifacts"
  echo " -c Install CogUtil"
  echo " -a Install AtomSpace"
  echo " -f Install from opencog github repo. Pass the name of the repo as an argument"
  echo " -o Install OpenCog"
  echo " -n Install notebook"
  echo " -l [master|java] Install Link Grammar release tarball; else master branch"
  echo " -m Install ASMOSES"
  echo " -z Install the language subsystem"
  echo " -g Install Guile $GUILEVERSION"
  echo " -b Build source code in git worktree found @ $PWD"
  echo " -e Build examples in git worktree found @ $PWD"
  echo " -t Run tests of source code in git worktree found @ $PWD"
  echo " -j [jobs] override number of auto-detected make jobs"
  echo " -w download data for the opencog repo"
  echo " -v Verbose output for 'apt-get' commands"
  echo " -h This help message"
else
  echo "Usage: $SELF_NAME [OPTIONS] [PACKAGE-TYPE]"
  echo "  PACKAGE-TYPES:"
  for key in ${!PACKAGE_DESCRIPTION[@]}; do
    echo "   " ${key} $'\t' "${PACKAGE_DESCRIPTION[$key]}"
  done
  echo "    (Live CD: Ubuntu ISO image ~700MB will be downloaded if none found.)"
  echo "  OPTIONS:"
  echo "    -i [filename]  ISO input  filename"
  echo "    -o [filename]  ISO output filename"
  echo "    -j [jobs]      override number of auto-detected make jobs"
  echo "    -n             supress git updates"
fi
}


# TODO: change octool usage to 'octool project command' format. Where projects
# are opencog, atomspace, cogutil... & commands are setup(for workspace),
# package(for docker,deb, rpm). Each will have various options/sub-commands.
#if [ $1 ] && [ "$SELF_NAME" != "$TOOL_NAME" ] ; then

if [ $# -eq 0 ] ; then NO_ARGS=true ; fi

if [ "$SELF_NAME" == "$TOOL_NAME" ] ; then
  while getopts "abdef:gipcrstl:mhvj:ownz" flag ; do
    case $flag in
      r)	ADD_REPOSITORIES=true ;;
      d)	INSTALL_DEPENDENCIES=true ;; #base development packages
      w)	DOWNLOAD_DATA=true ;;
      p)	INSTALL_OPENCOG_PYTHON_PACKAGES=true ;;
      c)	INSTALL_COGUTIL=true ;;
      a)	INSTALL_ATOMSPACE=true ;;
      f)	INSTALL_FROM_REPO="$OPTARG" ;;
      o)	INSTALL_OPENCOG=true ;;
      l)	INSTALL_LINK_GRAMMAR=true ;
        	if [ "$OPTARG" == "master" ]; then
        	  INSTALL_LG_MASTER=true
        	elif [ "$OPTARG" == "java" ]; then
        	  INSTALL_JAVA_LINK_GRAMMAR=true
        	fi ;;
      m)	INSTALL_ASMOSES=true ;;
      n)	INSTALL_NOTEBOOKS=true;;
      g)	INSTALL_GUILE=true ;;
      b)	BUILD_SOURCE=true ;;
      e)	BUILD_EXAMPLES=true ;;
      t)	TEST_SOURCE=true ;;
      v)	unset QUIET ;;
      z)	INSTALL_LANGUAGE=true ;;
      j)	MAKE_JOBS="$OPTARG" ;;
      s)	HASKELL_STACK_SETUP=true;;
      i)	INSTALL_BUILD=true ;;
      h)	usage ;;
      \?)	usage; exit 1 ;;
      *)  UNKNOWN_FLAGS=true ;;
    esac
  done
else
  while getopts ":i:o:j:s:c:l:r:adubtnxrvh" flag ; do
    case $flag in
      i)	INPUT_ISO_NAME="$OPTARG" ;;
      o)	OUTPUT_ISO_NAME="$OPTARG" ;;
      j)	MAKE_JOBS="$OPTARG" ;;          #override auto-detected MAKE_JOBS
      s)	HOST_SOURCE_BRANCH="$OPTARG" ;;
      c)	HOST_BUILD_DIR="$OPTARG" ;;     #local cached build dir
      l)	LIVE_BUILD_DIR="$OPTARG" ;;     #live build directory
      r)	BZR_REVISION="$OPTARG" ;;
      a)	ADD_REPOSITORIES=true ;;
      d)	INSTALL_DEPENDENCIES=true ;;    #ALL, none
      u)	UPDATE_OPENCOG=true ;;          #git pull
      b)	BUILD_OPENCOG=true ;;           #build opencog
      t)	TEST_OPENCOG=true ;;            #test opencog
      n)	unset DEFAULT_UPDATE_OPENCOG ;; #suppress git update
      x)	unset DEFAULT_BUILD_OPENCOG ;;  #suppress build
      p)	REINSTALL_PACKAGES=true ;;
      v)	unset QUIET ;;
      h)	usage ;;
      \?)	usage ;;
      *)  UNKNOWN_FLAGS=true ;;
    esac
  done
fi

shift $((OPTIND-1))

message() {
echo -e "\e[1;34m[$SELF_NAME] $MESSAGE\e[0m"
}

PACKAGE_TYPE=$DEFAULT_PACKAGE_TYPE

# This handles ./ocpkg runs, for e.g. `./ocpkg debs`
if [ $1 ] && [ "$SELF_NAME" != "ocpkg" ] ; then
 case $1 in
   debs)  PACKAGE_TYPE=$1 ;;
   dev)   PACKAGE_TYPE=$1 ;;
   demo)  PACKAGE_TYPE=$1 ;;
   kvm)   PACKAGE_TYPE=$1 ;;
   min)   PACKAGE_TYPE=$1 ;;
   local) PACKAGE_TYPE=$1 ;;
   docker) PACKAGE_TYPE=$1 ;;
   *)	  MESSAGE="Package type not recognized."; message ; usage ; exit 1 ;;
 esac
 MESSAGE="Package type: $PACKAGE_TYPE : ${PACKAGE_DESCRIPTION[$PACKAGE_TYPE]}" ; message
fi

#echo "[otheropts]==> $@"

# SECTION 3: Error handling & cleanup

debug() {
MESSAGE="Dropping to debugging chroot prompt..." ; message
chroot $LIVE_SQUASH_UNION /bin/bash -l
}

cleanup_squash() {
if [ -n "$LIVE_SQUASH_UNION" ]; then
  MESSAGE="Cleaning up squash temp space..." ; message
  fuser  $VERBOSE --mount $LIVE_SQUASH_UNION -kill
  sleep  $SLEEP_TIME
  umount $VERBOSE $LIVE_SQUASH_UNION/var/lib/apt/lists		|| true
  umount $VERBOSE $LIVE_SQUASH_UNION/var/cache/apt/archives	|| true
  umount $VERBOSE $LIVE_SQUASH_UNION/proc			|| true
  umount $VERBOSE $LIVE_SQUASH_UNION/sys			|| true
  umount $VERBOSE $LIVE_SQUASH_UNION/dev/pts			|| true
  umount $VERBOSE $LIVE_SQUASH_UNION$LIVE_BUILD_DIR		|| true
  umount $VERBOSE $LIVE_SQUASH_UNION$LIVE_SOURCE_BRANCH		|| true
  MESSAGE="Killing processes..." ; message
  fuser  $VERBOSE --mount $LIVE_SQUASH_UNION -kill
  sleep  $SLEEP_TIME
  umount -v -f $VERBOSE $LIVE_SQUASH_UNION			|| true
  rmdir  $VERBOSE $LIVE_SQUASH_UNION				|| true
fi

if [ -n "$LIVE_SQUASH_DELTA" ]; then
  echo " $LIVE_SQUASH_DELTA"
  rm -rf $LIVE_SQUASH_DELTA					|| true
fi

if [ -n "$UBUNTU_SQUASH_FILES" ]; then
  echo " $UBUNTU_SQUASH_FILES"
  umount $VERBOSE $UBUNTU_SQUASH_FILES				|| true
  rmdir  $VERBOSE $UBUNTU_SQUASH_FILES				|| true
fi
}

cleanup_iso() {
if [ -n       "$LIVE_ISO_UNION" ] ; then
  MESSAGE="Cleaning up ISO temp space..." ; message
  echo " $LIVE_ISO_UNION"
  umount $VERBOSE $LIVE_ISO_UNION				|| true
  rmdir  $LIVE_ISO_UNION					|| true
  df -m  $LIVE_ISO_UNION					|| true
fi

if [ -n       "$LIVE_ISO_DELTA" ] ; then
  echo " $LIVE_ISO_DELTA"
  rm -rf $LIVE_ISO_DELTA					|| true
fi

if [ -n "$UBUNTU_ISO_FILES" ] ; then
  echo " $UBUNTU_ISO_FILES"
  umount $VERBOSE $UBUNTU_ISO_FILES				|| true
  rmdir  $UBUNTU_ISO_FILES					|| true
  df -m  $UBUNTU_ISO_FILES					|| true
fi
}

exit_trap() {
if [ "$SELF_NAME" != "$TOOL_NAME" ] ; then
  MESSAGE="Exiting $SELF_NAME normally..." ; message
  cleanup_squash
  cleanup_iso
fi
}

quit_trap() {
if [ "$SELF_NAME" != "$TOOL_NAME" ] ; then
  MESSAGE="Exiting $SELF_NAME by request..." ; message
  cleanup_squash
  cleanup_iso
fi
}

error_trap() {
if [ "$SELF_NAME" != "$TOOL_NAME" ] ; then
  MESSAGE="Error trapped while running $SELF_NAME." ; message

  MESSAGE="Cleanup will run after debug." ; message
  debug
  cleanup_squash
  cleanup_iso
fi
}

trap error_trap ERR
trap exit_trap  EXIT
trap quit_trap  INT HUP QUIT TERM

# SECTION 4: Function Definitions

is_x68_64() {
ARCH=$(uname -m);
if [ "$ARCH" == "x86_64" ]; then
  return 0
else
  return 1
fi
}

get_distro_version() {
  cat /etc/os-release | grep "^VERSION_ID="  | cut -d "=" -f 2
}

UBUNTU_VERSION=$(get_distro_version)

add_repositories() {
MESSAGE="Adding software repositories..." ; message
for REPO in $REPOSITORIES ; do
  sudo apt-add-repository -y $REPO
done

sudo apt-get $QUIET --assume-yes update
}

get_github_latest_release() {
  local _user="$1"
  local _repo="$2"
  local _file_name="$3"

  # Getting the version and also accepting the file-name means that the
  # download will fail if the release is updated and the file-name has a
  # reference to the previous release, a hacky annoying reminder. If the
  # file-name has no reference to the version then all will go well.
  # TODO: Handle failure gracefully.
  local _version=$(curl https://github.com/"$_user"/"$_repo"/releases/latest \
    | cut -d "\"" -f 2 | cut -d "/" -f 8)
  echo $_user $_repo $_version
  rm -f $_file_name
  wget https://github.com/"$_user"/"$_repo"/releases/download/"$_version"/"$_file_name"
}

install_admin() {
MESSAGE="Installing sysadmin tools...." ; message
if ! sudo apt-get $QUIET --no-upgrade --assume-yes install $PACKAGES_ADMIN ; then
  MESSAGE="Please enable 'universe' repositories and re-run this script."  ; message
  exit 1
fi
}

# Install given opencog github repo
install_opencog_github_repo() {
  local REPO="$1"
  MESSAGE="Installing ${REPO}...." ; message
  cd /tmp/
  # cleaning up remnants from previous install failures, if any.
  rm -rf master.tar.gz* ${REPO}-master
  rm -rf master.tar.gz* ${REPO}-main
  wget https://github.com/opencog/${REPO}/archive/master.tar.gz
  tar -xvf master.tar.gz

  # Newer git repos call them `main` not `master`, cause #RacialJustice
  if [ -d ${REPO}-master/ ]
  then
      cd ${REPO}-master/
  fi
  if [ -d ${REPO}-main/ ]
  then
      cd ${REPO}-main/
  fi

  mkdir build
  cd build/
  cmake ..
  make -j$(nproc)
  sudo make install
  sudo ldconfig
  cd /tmp/
  rm -rf master.tar.gz ${REPO}-master/
  rm -rf master.tar.gz ${REPO}-main/
  cd $CURRENT_DIR
}

# Install cogutil
install_cogutil() {
  install_opencog_github_repo cogutil
}

# Install notebooks
install_notebooks() {
  MESSAGE="Installing notebooks...." ; message


  #####INSTALLING pip3 AND jupyter notebook
  install_python_pip
  cd
  sudo pip3 install ipython jupyter

  #####INSTALLING GUILE KERNEL#####
  # Check if site folder exits
  if [ ! -d "/usr/local/share/guile/site" ]
  then
    cd /usr/local/share/guile/
    sudo mkdir site
    cd
  fi

  # Install ZeroMQ library
  # ??? Really? Is this really needed?
  ## Clean up remenants of previous installations##
  rm -rf zeromq-4.2.1*
  wget https://github.com/zeromq/libzmq/releases/download/v4.2.1/zeromq-4.2.1.tar.gz
  tar xvf zeromq-4.2.1.tar.gz
  cd zeromq-4.2.1/
  ./configure
  make
  sudo make install
  cd

  # Install guile-json library
  ## Clean up remenants of previous installations##
  rm -rf guile-json-0.6.0*
  wget http://download.savannah.gnu.org/releases/guile-json/guile-json-0.6.0.tar.gz
  tar xvf guile-json-0.6.0.tar.gz
  cd guile-json-0.6.0
  ./configure --prefix=/usr/local/
  make
  sudo make install
  cd

  cd `guile -c "(display (%global-site-dir))"`
  # Place guile-simple-zmq library to the guile library folder
  sudo rm -rf simple-zmq.scm*
  sudo wget https://raw.githubusercontent.com/jerry40/guile-simple-zmq/master/src/simple-zmq.scm
  #edit simple-zmq.scm => set BUF-SIZE to 8192.
  sudo sed -i 's/(define BUF-SIZE.*)/(define BUF-SIZE 8192)/' simple-zmq.scm
  cd

  #Kernel setup
  if [ ! -d "/home/$USER/.local/share/jupyter/kernels/guile" ]
  then
      sudo mkdir /home/$USER/.local/share/jupyter/kernels/guile
  fi

  cd /home/$USER/.local/share/jupyter/kernels/guile
  sudo rm -rf guile-jupyter-kernel.scm hmac.scm kernel.json tools.scm
  sudo wget https://github.com/jerry40/guile-kernel/raw/master/src/guile-jupyter-kernel.scm
  sudo wget https://github.com/jerry40/guile-kernel/raw/master/src/hmac.scm
  sudo wget https://github.com/jerry40/guile-kernel/raw/master/src/kernel.json
  sudo wget https://github.com/jerry40/guile-kernel/raw/master/src/tools.scm
  sudo sed -i 's,\/home.*local,'$HOME/.local',' kernel.json

  echo "export PATH=$PATH:/home/$USER/.local/bin" >> /home/$USER/.bashrc
  echo "source $HOME/.bashrc"
  cd $CURRENT_DIR
}

# Install additional Python packages
# Except that there aren't any at this time....
install_opencog_python_packages() {
  MESSAGE="Installing base python packages...." ; message
  install_python
}

# Install Haskell Dependencies
install_haskell_dependencies(){
MESSAGE="Installing haskell dependencies in user space...." ; message
sudo wget -qO- https://get.haskellstack.org/ | sh

cd /tmp
rm -rf patchelf*
wget "https://nixos.org/releases/patchelf/patchelf-0.9/patchelf-0.9.tar.bz2"
tar -jxf patchelf-0.9.tar.bz2
rm patchelf-0.9.tar.bz2
cd patchelf-0.9
./configure
sudo make install
cd /tmp
rm -rf patchelf-0.9
cd $CURRENT_DIR
}

# The following sets the source & build directory for a project
set_source_and_build_dir() {
if [ "$(git rev-parse --is-inside-work-tree)" == true ] ; then
    SOURCE_DIR=$(git rev-parse --show-toplevel)
    MESSAGE="Source Directory is set to $SOURCE_DIR" ; message
    if [ -d $SOURCE_DIR/build ]; then
        BUILD_DIR=$SOURCE_DIR/build
        MESSAGE="Build Directory is set to $SOURCE_DIR/build" ; message
    else
        mkdir $SOURCE_DIR/build
        BUILD_DIR=$SOURCE_DIR/build
        MESSAGE="Build Directory is set to $SOURCE_DIR/build" ; message
    fi
else
    MESSAGE="Exiting $SELF_NAME as git worktree is not detected run inside \
a git worktree" ; message
    exit 1
fi
}

# Build function for cogutil, atomspace & asmoses repos
build_source() {
  set_source_and_build_dir
  if [ -a $BUILD_DIR/CMakeCache.txt ]; then
      rm $BUILD_DIR/CMakeCache.txt
      MESSAGE="Removed cmake cache file: rm $BUILD_DIR/CMakeCache.txt" ; message
  fi
  MESSAGE="cmake -B$BUILD_DIR -H$SOURCE_DIR" ; message
  #stackoverflow.com/questions/20610255/how-to-tell-cmake-where-to-put-build-files
  cmake -B$BUILD_DIR -H$SOURCE_DIR
  MESSAGE="make -C $BUILD_DIR -j$MAKE_JOBS" ; message
  make -C $BUILD_DIR -j$MAKE_JOBS
  MESSAGE="Finished building source" ; message
}

# Build examples function for atomspace & asmoses repos
build_examples() {
  set_source_and_build_dir
  if [ -a $BUILD_DIR/CMakeCache.txt ]; then
      rm $BUILD_DIR/CMakeCache.txt
      MESSAGE="Removed cmake cache file: rm $BUILD_DIR/CMakeCache.txt" ; message
  fi
  MESSAGE="cmake -B$BUILD_DIR -H$SOURCE_DIR" ; message
  #stackoverflow.com/questions/20610255/how-to-tell-cmake-where-to-put-build-files
  cmake -B$BUILD_DIR -H$SOURCE_DIR
  MESSAGE="make -C $BUILD_DIR  -j$MAKE_JOBS examples" ; message
  make -C $BUILD_DIR -j$MAKE_JOBS examples
  MESSAGE="Finished building examples" ; message
}

# Run tests function for cogutil, atomspace & asmoses repos
test_source() {
  set_source_and_build_dir
  if [ -a $BUILD_DIR/CMakeCache.txt ]; then
      rm $BUILD_DIR/CMakeCache.txt
      MESSAGE="Removed cmake cache file: rm $BUILD_DIR/CMakeCache.txt" ; message
  fi
  MESSAGE="cmake -B$BUILD_DIR -H$SOURCE_DIR" ; message
  #stackoverflow.com/questions/20610255/how-to-tell-cmake-where-to-put-build-files
  cmake -B$BUILD_DIR -H$SOURCE_DIR
  MESSAGE="make -C $BUILD_DIR -j$MAKE_JOBS test" ; message
  make -C $BUILD_DIR -j$MAKE_JOBS test #ARGS=-j$MAKE_JOBS
  MESSAGE="Finished building & running tests" ; message
}

# Install build job artifacts
install_build() {
  set_source_and_build_dir
  MESSAGE="Starting installation" ; message
  cd $BUILD_DIR
  sudo make install
  sudo ldconfig
  cd $CURRENT_DIR
  MESSAGE="Finished installation" ; message
}

# Install Core AtomSpace
install_atomspace(){
  install_opencog_github_repo atomspace
  install_opencog_github_repo atomspace-storage
  install_opencog_github_repo atomspace-pgres
  install_opencog_github_repo atomspace-rocks
  install_opencog_github_repo atomspace-cog
  install_opencog_github_repo cogserver
  install_opencog_github_repo unify
  install_opencog_github_repo sensory
  install_opencog_github_repo motor
}

# Install Language components
# This requires a re-install of Link Grammar, after the AtomSpace
# and after lg-atomese have been installed, because Link Grammar
# now uses the AtomSpace to hold dictionaries, and the lg-atomese
# Atom types to do it.
install_language() {
  install_opencog_github_repo lg-atomese
  install_link_grammar
  install_opencog_github_repo matrix
  install_opencog_github_repo learn
  install_opencog_github_repo generate
  install_opencog_github_repo vision
}

# Install all of OpenCog
install_opencog() {
  install_language
  install_opencog_github_repo ure
  install_opencog_github_repo attention
  install_opencog_github_repo spacetime
  install_opencog_github_repo pln
  install_opencog_github_repo miner
  install_opencog_github_repo asmoses
  install_opencog_github_repo opencog
  install_opencog_github_repo agi-bio
  install_opencog_github_repo benchmark
}

# Install ASMOSES
install_asmoses() {
  install_opencog_github_repo asmoses
}

# Install Link-Grammar
install_link_grammar(){
  # This uses the archive created by github to build and install link-grammar
  # The release at https://www.abisource.com/downloads/link-grammar isn't used
  # because the only additional value it provides is it gives a pre configured
  # tar ball, and its tls certificate breaks often. Such tar-bar can be released
  # by following instructions at
  # https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release
  MESSAGE="Installing Link-Grammar...." ; message
  cd /tmp/

  # cleaning up remnants from previous install failures, if any.
  rm -rf link-grammar*
  rm -rf master.tar.gz

  # Get install version from command line
  if [ $# -eq 1 ]; then
    local _version=${1}
    wget https://github.com/opencog/link-grammar/archive/link-grammar-${_version}.tar.gz
    tar -zxf link-grammar-${_version}.tar.gz
    cd link-grammar-link-grammar-${_version}/

  elif [ $INSTALL_LG_MASTER ]; then

    # Master version fails to follow naming convention
    local _version="master"
    wget https://github.com/opencog/link-grammar/archive/master.tar.gz
    tar -zxf master.tar.gz
    cd link-grammar-${_version}/
  else

    # Hunt down the latest tarball version. Abisource is dead.
    # local _version=$(wget -O - http://www.abisource.com/downloads/link-grammar/current/ \
    #  | grep md5 | awk 'match($0, /[5-9]\.[0-9]+\.[0-9]+/) {print substr($0, RSTART, RLENGTH)}')
    local _version=$(git ls-remote -t \
        https://github.com/opencog/link-grammar "link-grammar-5*" \
        | grep -v "\^"| cut -d "-" -f 3 | sort -V |tail -n 1 )
    wget https://github.com/opencog/link-grammar/archive/link-grammar-${_version}.tar.gz
    tar -zxf link-grammar-${_version}.tar.gz
    cd link-grammar-link-grammar-${_version}/
  fi
  ./autogen.sh --no-configure
  mkdir build
  cd build
  if [ $INSTALL_JAVA_LINK_GRAMMAR ]; then
    ../configure
  else
    ../configure --disable-java-bindings
  fi
  make -j$(nproc)
  sudo make install
  sudo ldconfig
  cd /tmp/
  rm -rf link-grammar*
  rm -rf master.tar.gz
  cd $CURRENT_DIR
}

install_bdwgc() {
  MESSAGE="Installing latest bdwgc ...." ; message
  # This used to work, but not any longer...!?
  # Apparently, the newest versions of curl behave differently!?
  # local _version=$(curl https://github.com/ivmai/bdwgc/releases/latest \
  #    | cut -d "\"" -f 2 | cut -d "/" -f 8)
  local _version=$(curl --silent -w %{redirect_url} https://github.com/ivmai/bdwgc/releases/latest \
      | cut -d "\"" -f 2 | cut -d "/" -f 8)

  local _dir_name="gc-${_version:1}"

  # Apparently, the github download URL's have changed.
  local _file_name="${_dir_name}.tar.gz"
  local _download_name="${_version}/${_dir_name}.tar.gz"

  cd /tmp/
  rm -rf ${_dir_name}*
  get_github_latest_release ivmai bdwgc ${_download_name}
  tar -xvf ${_file_name}
  cd ${_dir_name}
  ./configure --enable-large-config
  make -j$(nproc)
  sudo make install
  sudo ldconfig
  cd /tmp/
  rm -rf ${_dir_name}*
}

install_python() {
  MESSAGE="Installing python3 ...." ; message
  sudo apt-get install -y --no-install-recommends python3-dev python3-dev

  if [[ "$UBUNTU_VERSION" = "\"20.04\"" ]]; then
    sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 2
    sudo apt-get install -y --no-install-recommends python3-nose cython3
  fi
  if [[ "$UBUNTU_VERSION" = "\"22.04\"" ]]; then
    sudo apt-get install -y --no-install-recommends python3-nose cython3
  fi
  if [[ "$UBUNTU_VERSION" = "\"24.04\"" ]]; then
    sudo apt-get install -y --no-install-recommends python3-nose cython3
  fi
}

# Install pip seperately. The problem here is that installing pip
# breaks python in ways that I cannot figure out. So punt, until some
# python guru shows up and fixes this stuff.
install_python_pip() {
  MESSAGE="Installing python3 pip...." ; message
  sudo apt-get install -y --no-install-recommends python3-pip
  sudo pip3 install -U pip setuptools
}


install_guile() {
    install_bdwgc
    MESSAGE="Installing guile-$GUILEVERSION...." ; message
    cd /tmp/
    # Clean up remnants from previous install failures, if any.
    rm -rf guile-${GUILEVERSION}*
    wget https://ftp.gnu.org/gnu/guile/guile-$GUILEVERSION.tar.gz
    tar -xvf guile-$GUILEVERSION.tar.gz
    cd guile-$GUILEVERSION
    mkdir build
    cd build
    ../configure
    make -j$(nproc)
    sudo make install
    sudo mv  /usr/local/lib/libguile-*.so.*-gdb.scm /usr/share/gdb/auto-load/
    sudo ldconfig
    cd /tmp/
    rm -rf guile-${GUILEVERSION}*
}

# atomspace unit tests have UTF-8 test cases
# link-grammar needs a smattering of locales
ensure_UTF_installed() {
    if locale -a | grep -q en_US.utf8
    then
        echo UTF-8 locale enabled already
    else
        sudo sh -c 'echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "ar_AE.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "de_DE.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "fa_IR.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "he_IL.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "id_ID.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "kk_KZ.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "lt_LT.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "ru_RU.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "th_TH.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "tr_TR.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "vi_VN.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo sh -c 'echo "zh_HK.UTF-8 UTF-8" >> /etc/locale.gen'
        sudo locale-gen
    fi
}

# In Ubuntu 18.04 some links are absent when build-essential and ccache
# packages are installed by same apt-get command
update_ccache_links() {
  sudo update-ccache-symlinks
}

# Install system dependencies
install_dependencies() {
  # Install the latest python3 version before everything else
  install_python

  MESSAGE="Installing OpenCog build dependencies...." ; message
  if ! sudo apt-get $QUIET --no-upgrade --assume-yes --no-install-recommends install $PACKAGES_BUILD $PACKAGES_RUNTIME $PACKAGES_FETCH liboctomap-dev locales ; then
    exit 1
  fi
  ensure_UTF_installed

  # Update ccache links
  update_ccache_links

  # Install guile >3.0.0 also install bdwgc for language-learning
  install_guile
}

# Download data
download_data() {
  DOWNLOAD_DIR="$HOME/.opencog/data"
  MESSAGE="Downloading OpenCog's datasets to $DOWNLOAD_DIR ...." ; message
  if [ ! -d "$DOWNLOAD_DIR" ]; then
    mkdir -p "$DOWNLOAD_DIR"
  fi

  if [ ! -f "$DOWNLOAD_DIR/gtwc-en-333333-words.scm" ]; then
    wget -O "$DOWNLOAD_DIR/gtwc-en-333333-words.scm" \
      https://raw.githubusercontent.com/opencog/test-datasets/master/concept_nodes/gtwc-en-333333-words.scm
  fi
}

update_opencog_source() {
if sudo apt-get --no-upgrade --assume-yes $QUIET install $PACKAGES_FETCH ; then
  echo -n
else
  MESSAGE="Please enable 'universe' repositories and re-run this script."  ; message
exit 1
fi
OPENCOG_SOURCE_DIR=$LIVE_SOURCE_BRANCH
mkdir -p $OPENCOG_SOURCE_DIR || true
if [ ! "$(ls -A $OPENCOG_SOURCE_DIR/.git)" ]; then
  MESSAGE="Fetching OpenCog source at $OPENCOG_SOURCE_DIR..." ; message
  git clone https://github.com/opencog/opencog $OPENCOG_SOURCE_DIR
else
  if [ $UPDATE_OPENCOG ] ; then
    MESSAGE="Updating OpenCog source at $OPENCOG_SOURCE_DIR..." ; message
    cd $OPENCOG_SOURCE_DIR
    git pull
    cd -
  fi
fi
}

build_opencog() {
mkdir -p -v $LIVE_BUILD_DIR || true
cd $LIVE_BUILD_DIR
MESSAGE="cmake $LIVE_SOURCE_BRANCH" ; message
cmake $LIVE_SOURCE_BRANCH
MESSAGE="make -j$MAKE_JOBS" ; message
make -j$MAKE_JOBS

if [ $TEST_OPENCOG ] ; then
  make test
fi

case $PACKAGE_TYPE in
  min)	MESSAGE="Installing OpenCog..." ; message
 	make install; exit 0;;
  demo)	MESSAGE="Installing OpenCog..." ; message
  	make install; exit 0;;
  dev)	exit 0;;
esac

}

locate_live_iso() {
if [ $INPUT_ISO_NAME ]; then
  MESSAGE="Using Ubuntu image specified at $INPUT_ISO_NAME" ; message
  UBUNTU_ISO_IMAGE=$INPUT_ISO_NAME
else
  UBUNTU_LOCATIONS=$(locate --existing --basename "\\$UBUNTU_ISO" | grep $HOME)
  for LOC in $UBUNTU_LOCATIONS ; do
    MESSAGE="Ubuntu image found at $LOC. Checksumming, please wait..." ; message
    LOC_MD5SUM=$(md5sum $LOC | awk '{print $1}')
  if [ "$LOC_MD5SUM" == "$UBUNTU_MD5SUM" ] ; then
    UBUNTU_ISO_IMAGE=$LOC
    MESSAGE="Using image found at $UBUNTU_ISO_IMAGE." ; message
    break
  else
    MESSAGE="...checksum failed." ; message
  fi
done
fi
if [ ! -f $UBUNTU_ISO_IMAGE ] ; then
 #aria2c --seed-time=0 ${UBUNTU_URL}${UBUNTU_ISO}.torrent
 UBUNTU_ISO_IMAGE=${UBUNTU_ISO}
fi
}

remove_packages() {
MESSAGE="$PACKAGE_TYPE install type: Removing unecessary packages..." ; message
chroot $LIVE_SQUASH_UNION apt-get --no-upgrade --assume-yes $QUIET purge $PACKAGES_REMOVE --auto-remove
chroot $LIVE_SQUASH_UNION apt-get --no-upgrade --assume-yes $QUIET autoremove
# stupid stupid stupid hack
chroot $LIVE_SQUASH_UNION service cups stop
}

reinstall_removed() {
MESSAGE="Re-installing removed packages..." ; message
apt-get --no-upgrade --assume-yes $QUIET install $PACKAGES_REMOVE
}

keep_source() {
MESSAGE="$PACKAGE_TYPE install type: Keeping source code..." ; message
chroot $LIVE_SQUASH_UNION chown -R 999 $LIVE_SOURCE_BRANCH $LIVE_BUILD_DIR || true
chroot $LIVE_SQUASH_UNION mkdir -p /home/$LIVE_USERNAME/Desktop/ || true
chroot $LIVE_SQUASH_UNION ln -s "$LIVE_SOURCE_BRANCH" "/home/$LIVE_USERNAME/Desktop/$LIVE_DESKTOP_SOURCE" || true
}

remove_source() {
MESSASGE="$PACKAGE_TYPE install type: Removing source code..." ; message
chroot $LIVE_SQUASH_UNION umount $VERBOSE $LIVE_SOURCE_BRANCH
}

remove_build() {
MESSAGE="$PACKAGE_TYPE install type: Removing build files..." ; message
echo umount $VERBOSE $LIVE_SQUASH_UNION$LIVE_BUILD_DIR
umount $VERBOSE $LIVE_SQUASH_UNION$LIVE_BUILD_DIR || true
rm -rf $LIVE_SQUASH_UNION$LIVE_BUILD_DIR || true
}

remove_dev_debs() {
MESSAGE="$PACKAGE_TYPE install type: Removing development packages..." ; message
chroot $LIVE_SQUASH_UNION apt-get --no-upgrade --assume-yes purge $PACKAGES_BUILD $PACKAGES_EXDEV --auto-remove
chroot $LIVE_SQUASH_UNION apt-get $QUIET autoremove --assume-yes
}

remove_doc_debs() {
MESSAGE="$PACKAGE_TYPE install type: Removing documentation packages..." ; message
chroot $LIVE_SQUASH_UNION apt-get --no-upgrade --assume-yes purge $PACKAGES_DOC --auto-remove
chroot $LIVE_SQUASH_UNION apt-get $QUIET autoremove --assume-yes
}

install_package_tools() {
MESSAGE="Installing packaging tools..." ; message
if sudo apt-get --no-upgrade --assume-yes $QUIET -y install $PACKAGES_TOOLS ; then
 echo -n
else
 MESSAGE="Please enable 'universe' repositories and re-run this script."  ; message
 exit 1
fi
}

mount_live_iso() {
MESSAGE="Mounting Ubuntu ISO image..." ; message

UBUNTU_ISO_FILES=$(mktemp -d --suffix=.UBUNTU_ISO_FILES)
mount $VERBOSE -o ro -o loop -t iso9660 $UBUNTU_ISO_IMAGE $UBUNTU_ISO_FILES

MESSAGE="Mounting Ubuntu compressed filesystem..." ; message

UBUNTU_SQUASH_BLOB="$UBUNTU_ISO_FILES/casper/filesystem.squashfs"

if ! [ -e "$UBUNTU_SQUASH_BLOB" ] ; then
  MESSAGE="Could not find the Ubuntu squashfs at '$UBUNTU_SQUASH_BLOB'." ; message
  umount $VERBOSE $UBUNTU_ISO_FILES || true
  exit 1
fi

LIVE_ISO_DELTA=$(mktemp -d --suffix=.LIVE_ISO_DELTA)
LIVE_ISO_UNION=$(mktemp -d --suffix=.LIVE_ISO_UNION)
mount $VERBOSE -t overlayfs -o upperdir=$LIVE_ISO_DELTA,lowerdir=$UBUNTU_ISO_FILES none $LIVE_ISO_UNION

#MESSAGE="Mounting read-only Ubuntu compressed filesystem..." ; message

UBUNTU_SQUASH_FILES=$(mktemp -d --suffix=.UBUNTU_SQUASH_FILES)
mount $VERBOSE -o loop -t squashfs $UBUNTU_SQUASH_BLOB $UBUNTU_SQUASH_FILES

#MESSAGE="Creating temporary workplace for remastering new compressed files..." ; message

LIVE_SQUASH_DELTA=$(mktemp -d --suffix=.LIVE_SQUASH_DELTA)
LIVE_SQUASH_UNION=$(mktemp -d --suffix=.LIVE_SQUASH_UNION)
mount $VERBOSE -t overlayfs -o upperdir=$LIVE_SQUASH_DELTA,lowerdir=$UBUNTU_SQUASH_FILES none $LIVE_SQUASH_UNION
chmod +rx $LIVE_SQUASH_UNION

MESSAGE="Setting up chroot environment..." ; message

DISTRIB_ID=$(awk '/DISTRIB_ID=/' $LIVE_SQUASH_UNION/etc/lsb-release | sed 's/DISTRIB_ID=//' | tr '[:upper:]' '[:lower:]')
DISTRIB_CODENAME=$(awk '/DISTRIB_CODENAME=/' $LIVE_SQUASH_UNION/etc/lsb-release | sed 's/DISTRIB_CODENAME=//' | tr '[:upper:]' '[:lower:]')
LIVE_USERNAME=$DISTRIB_ID
LIVE_BUILD_DIR=/home/$LIVE_USERNAME/build

cp $LIVE_SQUASH_UNION/etc/resolv.conf      $LIVE_SQUASH_UNION/etc/resolv.conf.bak || true
cp $LIVE_SQUASH_UNION/etc/apt/sources.list $LIVE_SQUASH_UNION/etc/apt/sources.list.bak || true
cp /etc/resolv.conf      $LIVE_SQUASH_UNION/etc
cp /etc/apt/sources.list $LIVE_SQUASH_UNION/etc/apt
if [ -f /etc/apt/apt.conf.d/01apt-cacher-ng-proxy ] ; then
 cp /etc/apt/apt.conf.d/01apt-cacher-ng-proxy  $LIVE_SQUASH_UNION/etc/apt/apt.conf.d/01apt-cacher-ng-proxy
fi

cp $0 $LIVE_SQUASH_UNION$PATH_PREFIX/bin/$SELF_NAME ; chmod ugo+rx $LIVE_SQUASH_UNION$PATH_PREFIX/bin/$SELF_NAME
cd $LIVE_SQUASH_UNION$PATH_PREFIX/bin
ln -s $SELF_NAME $TOOL_NAME
cd $CURRENT_DIR

MESSAGE="Mounting filesystems..." ; message

chroot $LIVE_SQUASH_UNION mount $VERBOSE -t proc none /proc
chroot $LIVE_SQUASH_UNION mount $VERBOSE -t sysfs none /sys
chroot $LIVE_SQUASH_UNION mount $VERBOSE -t devpts none /dev/pts

mkdir -p $LIVE_SQUASH_UNION/var/cache/apt/archives
mkdir -p $LIVE_SQUASH_UNION/var/lib/apt/lists
mkdir -p $HOST_SOURCE_BRANCH
mkdir -p $LIVE_SQUASH_UNION/$LIVE_SOURCE_BRANCH

mount $VERBOSE -o bind /var/cache/apt/archives $LIVE_SQUASH_UNION/var/cache/apt/archives
mount $VERBOSE -o bind /var/lib/apt/lists $LIVE_SQUASH_UNION/var/lib/apt/lists
mount $VERBOSE -o bind $HOST_SOURCE_BRANCH $LIVE_SQUASH_UNION/$LIVE_SOURCE_BRANCH
}

prepare_live_iso() {

fuser  $VERBOSE --mount $LIVE_SQUASH_UNION -kill
sleep  $SLEEP_TIME
umount $VERBOSE $LIVE_SQUASH_UNION/proc || true
umount $VERBOSE $LIVE_SQUASH_UNION/sys || true
umount $VERBOSE $LIVE_SQUASH_UNION/dev/pts|| true
umount $VERBOSE $LIVE_SQUASH_UNION/var/lib/apt/lists || true
umount $VERBOSE $LIVE_SQUASH_UNION/var/cache/apt/archives || true

#replace original config files
cp $LIVE_SQUASH_UNION/etc/resolv.conf.bak      $LIVE_SQUASH_UNION/etc/resolv.conf || true
cp $LIVE_SQUASH_UNION/etc/apt/sources.list.bak $LIVE_SQUASH_UNION/etc/apt/sources.list || true

if [ -f  $LIVE_SQUASH_UNION/etc/apt/apt.conf.d/01apt-cacher-ng-proxy ]; then
  rm $LIVE_SQUASH_UNION/etc/apt/apt.conf.d/01apt-cacher-ng-proxy
fi
}

write_live_media() {
MESSAGE="Creating new compressed filesystem..." ; message
mksquashfs $LIVE_SQUASH_UNION $LIVE_ISO_UNION/casper/filesystem.squashfs $SQUASHFS_OPTIONS
printf $(sudo du -sx --block-size=1 $LIVE_SQUASH_UNION | cut -f1) > $LIVE_ISO_UNION/casper/filesystem.size
MESSAGE="Creating new bootable ISO image..." ; message
mkisofs -D -r -V $OUTPUT_ISO_LOCATION/$OUTPUT_ISO_NAME -cache-inodes -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o "$OUTPUT_ISO_LOCATION/$OUTPUT_ISO_NAME" $LIVE_ISO_UNION
MESSAGE="Wrote $(du -sm $OUTPUT_ISO_LOCATION/$OUTPUT_ISO_NAME)MB ..." ; message
chown $VERBOSE $SUDO_USER $OUTPUT_ISO_LOCATION/$OUTPUT_ISO_NAME
cleanup_squash
cleanup_iso
}

# SECTION 5: Main Program (MAIN main)

# This is mainly for configuring workspaces depending on the type
# of project being worked on. The order here matters.
if [ "$SELF_NAME" == "$TOOL_NAME" ] ; then
    if [ $UNKNOWN_FLAGS ] ; then usage; exit 1 ; fi
    if [ $NO_ARGS ] ; then usage; exit 1 ; fi
    if [ $ADD_REPOSITORIES ] ; then add_repositories ; fi
    if [ $INSTALL_DEPENDENCIES ] ; then install_dependencies ; fi
    if [ $DOWNLOAD_DATA ] ; then download_data ; fi
    if [ $HASKELL_STACK_SETUP ] ; then install_haskell_dependencies ; fi
    if [ $INSTALL_OPENCOG_PYTHON_PACKAGES ] ; then install_opencog_python_packages ; fi
    if [ $INSTALL_COGUTIL ] ; then install_cogutil ; fi
    if [ $INSTALL_ATOMSPACE ] ; then install_atomspace ; fi
    if [ $INSTALL_LANGUAGE ] ; then install_language ; fi
    if [ $INSTALL_FROM_REPO ] ; then install_opencog_github_repo "$INSTALL_FROM_REPO" ; fi
    if [ $INSTALL_NOTEBOOKS ] ; then install_notebooks ; fi
    if [ $INSTALL_OPENCOG ] ; then install_opencog ; fi
    if [ $INSTALL_LINK_GRAMMAR ] ; then install_link_grammar ; fi
    if [ $INSTALL_ASMOSES ] ; then install_asmoses ; fi
    if [ $INSTALL_GUILE ] ; then install_guile ; fi
    if [ $BUILD_SOURCE ] ; then build_source ; fi
    if [ $INSTALL_NOTEBOOKS ] ; then install_notebooks ; fi
    if [ $BUILD_EXAMPLES ] ; then build_examples ; fi
    if [ $TEST_SOURCE ] ; then test_source ; fi
    if [ $INSTALL_BUILD ] ; then install_build ; fi
exit 0
fi

# option flag conditionals are finished, so set defaults

if [ ! $ADD_REPOSITORIES ] ; then ADD_REPOSITORIES=$DEFAULT_ADD_REPOSITORIES; fi
if [ ! $INSTALL_DEPENDENCIES ] ; then INSTALL_DEPENDENCIES=$DEFAULT_INSTALL_DEPENDENCIES; fi
if [ ! $UPDATE_OPENCOG ] ; then UPDATE_OPENCOG=$DEFAULT_UPDATE_OPENCOG; fi
if [ ! $BUILD_OPENCOG ] ; then BUILD_OPENCOG=$DEFAULT_BUILD_OPENCOG; fi
if [ ! $TEST_OPENCOG ] ; then TEST_OPENCOG=$DEFAULT_TEST_OPENCOG; fi

# package type selected when invoked as 'ocpkg'

case $PACKAGE_TYPE in
  demo)	install_package_tools; locate_live_iso ; mount_live_iso ; remove_packages ;;
  min)	install_package_tools; locate_live_iso ; mount_live_iso ; remove_packages ;;
  dev)	install_package_tools; locate_live_iso ; mount_live_iso
      	MESSAGE="$PACKAGE_TYPE install type: Keeping all Ubuntu packages..." ; message ;;
esac

case $PACKAGE_TYPE in
  local) add_repositories ; install_dependencies ;;
  demo)  chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -a -d ;;
  min)   chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -a -d ;;
  dev)   chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -a -d ;;
esac

case $PACKAGE_TYPE in
  local) if [ $UPDATE_OPENCOG ] ; then update_opencog_source ; fi ;;
  demo)  if [ $UPDATE_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -u ; fi ;;
  min)   if [ $UPDATE_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -u ; fi ;;
  dev)   if [ $UPDATE_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -u ; fi ;;
esac

case $PACKAGE_TYPE in
  local) if [ $BUILD_OPENCOG ] ; then build_opencog ; fi ;;
  demo)  if [ $BUILD_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -b ; fi ;;
  min)   if [ $BUILD_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -b ; fi ;;
  dev)   if [ $BUILD_OPENCOG ] ; then chroot $LIVE_SQUASH_UNION $PATH_PREFIX/bin/$TOOL_NAME $VERBOSE -b ; fi ;;
esac

case $PACKAGE_TYPE in
  min)	remove_dev_debs ; remove_doc_debs ; remove_source ; remove_build ;;
  demo)	remove_dev_debs ; remove_doc_debs ; remove_source ; remove_build ;;
  dev)	keep_source  ;;
esac

case $PACKAGE_TYPE in
  min)  prepare_live_iso ; write_live_media ;;
  demo) prepare_live_iso ; write_live_media ;;
  dev)  prepare_live_iso ; write_live_media ;;
esac