#!/bin/sh
#
# COPYRIGHT (c) 2022 The Fellowship of SML/NJ (http://www.smlnj.org)
# All rights reserved.
#
# usage: installml [ options ]
#   options:
#       -boot           -- gzip a tarball of the boot files and copy it to the root
#       -clean          -- remove existing pre-compiled libraries and executables
#       -cleanall       -- like "-clean" but also removes CM metadata files
#

#!/bin/sh

# The tmpfile is for pathconfig editing (see below).
tmpfile=pathconfig.tmp.$$

trap 'rm -f $tmpfile; exit 1' 1 2 3 15

this=$0
HERE=`pwd`
cd ..
ROOT=`pwd`
cd "$HERE"

#
# Parse command line
#
CLEAN=false
CLEAN_CM=false
INSTALL_BOOTFILES=no
STEM=sml
# Process command-line arguments
#
while [ "$#" != "0" ] ; do
  arg=$1; shift
  case $arg in
    -boot)
      INSTALL_BOOTFILES=yes
      ;;
    -clean)
      CLEAN=true
      ;;
    -cleanall)
      CLEAN=true
      CLEAN_CM=true
      ;;
    *)
# TODO: check for excess arguments
      STEM=$arg
      ;;
  esac
done

MAIN_HEAP_DIR="$ROOT/bin/.heap"
MAIN_LIB_DIR="$ROOT/lib"
MAIN_CONFIG_DIR="$ROOT/config"

# A function to move all stable library files to a parallel directory
# hierarchy.
# The first argument must be a simple path (no / inside), and
# the second argument must be an absolute path.
move() {
  if [ -d "$1" ] ; then
    if [ ! -d "$2" ] ; then
      if [ -f "$2" ] ; then
        echo $this: '$2' exists as a non-directory.
        exit 1
      fi
      mkdir "$2"
    fi
    cd "$1"
    for i in * .[a-zA-Z0-9]* ; do
      move $i "$2/$i"
    done
    cd ..
  elif [ -f "$1" ] ; then
    rm -f "$2"
    mv "$1" "$2"
  fi
}

make_tarball() {
  if [ x"$OPSYS" = xdarwin ] ; then
     TARFLAGS="--no-mac-metadata $TARFLAGS"
  fi
  tar $TARFLAGS -czf "$1" "$2" || exit 1
}

if [ -f "$ROOT/bin/.arch-n-opsys" ]; then
  ARCH_N_OPSYS=`"$ROOT/bin/.arch-n-opsys"`
  if [ "$?" = "0" ]; then
    eval $ARCH_N_OPSYS
  else
    echo "$this: Cannot determine architecture/os."
    exit 1
  fi
fi

if [ x"$INSTALL_BOOTFILES" = xyes ] ; then
  BOOTARCHIVE="$ROOT"/boot."$ARCH"-unix.tgz
  BOOTFILES=sml.boot."$ARCH"-unix
  if [ -d $BOOTFILES ] ; then
    if [ -f "$BOOTARCHIVE" ] ; then
      echo "$this: removing existing boot-file archive"
      rm -f "$BOOTARCHIVE"
    fi
    make_tarball "$BOOTARCHIVE" $BOOTFILES
  else
    echo "$this: The directory $BOOTFILES is missing."
    exit 1
  fi
fi

HEAP_FILE=$STEM.$HEAP_SUFFIX
LIB_DIR=$STEM.lib

if [ ! -f $HEAP_FILE ] ; then
  echo "$this: The heap file $HEAP_FILE is missing."
  exit 1
fi

if [ ! -d $LIB_DIR ] ; then
  echo "$this: The library directory $LIB_DIR is missing."
  exit 1
fi

# source directories (other than cm, compiler, and system) that might have ".cm" files
SRC_DIRS="\
  smlnj-lib \
  libraries \
  tools \
  "

if $CLEAN ; then
  echo "cleaning $MAIN_LIB_DIR and $MAIN_HEAP_DIR"
  rm -rf "$MAIN_LIB_DIR"/* "$MAIN_HEAP_DIR"/*
  if $CLEAN_CM ; then
    echo "removing old CM files"
    for d in $SRC_DIRS ; do
      if [ -d "$ROOT/$d" ] ; then
        find "$ROOT/$d" \( -name .cm -exec rm -rf {} \; -prune -print \)
      fi
    done
  fi
fi

#
# create heap and lib directories, if necessary
#
if test ! -d "$MAIN_HEAP_DIR" ; then
  mkdir -p "$MAIN_HEAP_DIR"
fi
if test ! -d "$MAIN_LIB_DIR" ; then
  mkdir -p "$MAIN_LIB_DIR"
fi

# Moving the heap image to its place
mv $HEAP_FILE "$MAIN_HEAP_DIR/sml.$HEAP_SUFFIX"

# Moving each individual library...
cd "$LIB_DIR"
for anchor in * ; do
  if [ -d $anchor ] ; then
    move $anchor "$MAIN_LIB_DIR/$anchor"
  fi
done
cd ..

# Update the pathconfig file in $MAIN_LIB_DIR
#  The awk script below replaces the original binding in $pcfile
#  with its fresh counterpart should there be one.  Other bindings
#  are retained and brand new ones are added.
pcfile="$MAIN_LIB_DIR/pathconfig"
if [ -f "$pcfile" ] ; then
  cp "$pcfile" "$tmpfile"
fi
rm -f "$pcfile"
cat "$LIB_DIR/pathconfig" >>"$tmpfile"
if [ -f "$MAIN_CONFIG_DIR/extrapathconfig" ] ; then
  cat "$MAIN_CONFIG_DIR/extrapathconfig" >>"$tmpfile"
fi
awk <"$tmpfile" 'NF == 2 { mapping[$1] = $2 }
NF != 2 { print $0 }
END { for (i in mapping) print i, mapping[i] }' \
 | sort >"$pcfile"

rm -r "$LIB_DIR"
rm -f "$tmpfile"
