#!/bin/sh

umask 022

if [ .$INSTALLLANG = "." ]; then
   INSTALLLANG=English
   export INSTALLLANG
fi

if [ ! -d TextResources ]; then
   echo "Cannot find TextResources directory."
   echo
   echo "Installer aborting..."
   exit 1
fi

textres=`pwd`/TextResources/$INSTALLLANG
export textres

utils=`pwd`/SystemResources/Utilities
export utils

PATH=Binaries/$INSTALLARCH:$utils:$PATH
export PATH

if [ -f $textres/Banner ]; then
   cat $textres/Banner
else
   printm Banner
fi
if [ .$INSTALLARCH = "." ]; then
   printm NoInstArch
   exit 1
fi

# initialization

checkfiles=1
verbose=0
debug=0
safe=0
usage=0
install_type="X"
export install_type
skippw=0

# We prompt for device or target directory based on media
# manifest file.

while
   test ."$1" != .""
do
   case "$1"
   in

   -pass)
       if [ $install_type != X ]; then
          usage=1
       fi 
       if [ $skippw -eq 1 ]; then 
          printm PassNoPass
          exit 1
       fi
       install_type="p"
       export install_type
       shift
       ;;

   -nopass)
       skippw=1
        if [ $install_type = "p" ]; then
        printm PassNoPass
        exit 1
        fi
       shift
       ;;

   -info)
       mathinfovar=`mathinfo`
       hostnamevar=`echo $mathinfovar | awk '{print $1}'`
       mathidvar=`echo $mathinfovar | awk '{print $2}'`
       printm PassInfo $hostnamevar $mathidvar
       # this may not be appropriate
       exit 0
       ;;

   -verbose) verbose=1
       shift
       ;;

   -tmp) 
       if [ .$2 != . -a -d $2/. ]; then
          TMPDIR=$2
          export TMPDIR
          shift 2
       else
          shift
          usage=1
       fi
       ;;

   -sys) 
       if [ .$2 != . ]; then
          INSTALLARCH=$2
          export INSTALLARCH
          shift 2
       else
          shift
          usage=1
       fi
       ;;

   -default)
       if [ $install_type != X ]; then
          usage=1
       fi 
       install_type="a"
       export install_type
       shift
       ;;

   -cmdir)
       if [ .$2 != . ]; then
          CMDDIR=$2
          export CMDDIR
          echo $CMDDIR > $ITMPDIR/CommandDir
          echo "var cmddir $CMDDIR" >> $ITMPDIR/InstEnv
          shift 2
       else
          shift
          usage=1
       fi
       ;;

   -auto) 
       if [ $install_type != X ]; then
          usage=1
       fi 
       install_type="A"
       export install_type
       shift
       ;;

   -custom)
       if [ $install_type != X ]; then
          usage=1
       fi 
       install_type="c"
       export install_type
       shift
       ;;

   -dir) 
       if [ .$2 != . ]; then
          TARGET=$2
          export TARGET
          shift 2
       else
          shift
          usage=1
       fi
       ;;

   -lang) if [ .$2 != . -a -f TextResources/$2/InstallUsage ]; then
          INSTALLLANG=$2
          export INSTALLLANG
          textres=`pwd`/TextResources/$2
          export textres
          shift 2
       else
          printm InvalidLanguage $2
          shift
          usage=1
       fi
       ;;

   -Verbose) debug=1
       verbose=1
       shift
       ;;

   -print) safe=1
       shift
       ;;

   -template) 
       if [ .$2 != . ]; then
          if [ -f $2 ]; then
             template=$2
             shift 2
          else
             shift
             usage=1
          fi
       else
          shift
          usage=1
       fi
       ;;

   -n) checkfiles=0
       shift
       ;;

   -from) 
       if [ .$2 != . ]; then
          SRCDIR=$2
          shift 2
       else
          shift
          usage=1
       fi
       ;;

   -mandir)
       if [ .$2 != . ]; then
          MANDIR=$2
          export MANDIR
          shift 2
       else
          shift
          usage=1
       fi
       ;;


   -h|-help|-) usage=1
       shift
       ;;

    *) usage=1
       # Have to print this in English; no language yet
       echo "MathInstaller: Unknown option $1"
       shift
       ;;

    esac
done

# We need to set up text resources early, so we can handle messages

if [ $usage -ne 0 ]; then
   cat $textres/InstallUsage
   exit 1
fi

# Pre install checks, some debug messages, etc.

if [ $debug -ne 0 ]; then
   echo " "
   echo ">>> Installer system type set to $INSTALLARCH."
   echo " "
   echo ">>> Temporary files directory set to $TMPDIR."
   echo " "
   echo ">>> Text Resources located in $textres"
   echo " " 
fi

# Check argument consistency

if [ .$install_type = "." ]; then
   install_type="a"
   export install_type
fi

if [ ! -d $TMPDIR ]; then
   printm NoTempDir $TMPDIR
   exit 1
fi

ITMPDIR=$TMPDIR/MI$$
export ITMPDIR

mkdir $ITMPDIR

if [ ! -d $ITMPDIR ]; then
   printm NoTempPerm $TMPDIR
   exit 1
fi

if [ $install_type = "A" ]; then
    touch $ITMPDIR/Quiet
fi

if [ $verbose = "1" ]; then
   rm -f $ITMPDIR/Quiet
fi

trap "cleanup; exit 1" 2 1

# echo test

echo "this is a test\c" | grep -s c > /dev/null 2>&1
if [ ! "$?" = "0" ] ; then
    n=''
    c='\c'
else
    n='-n'
    c=''
fi
export n
export c

# If this is a floppy or tape install, the media manifest must
# be on the first volume or file. We actually get the media type
# from the media manifest.

# Manifest locations

media_manifest=`pwd`/SystemResources/Manifests/media
comp_manifests=`pwd`/SystemResources/Components

if [ ! -f $media_manifest ]; then
   printm NoMediaManifest 
   cleanup
   exit 1
fi

if [ $debug -eq 1 ]; then
   echo ">>> Media type manifest is $media_manifest."
   echo ">>> Component manifests are in $comp_manifests."
fi

media=`getmedia`

# Set the source and the target directory, but this prompt has
# to be a little different based on the media.

if [ $media = "tape" ]; then
   echo "Tape installation not currently available."
   cleanup
   exit 1
elif [ $media = "CD" ]; then
   if [ .$TARGET = . ]; then
      printm TopDir
      promptname=TopDir; defanswer=${DEFAULT_TOPDIR-'/usr/local/mathematica'}; . printp;
      while (chkdir $curans); do
         promptname=TopDir; defanswer=${DEFAULT_TOPDIR-'/usr/local/mathematica'}; . printp;
      done
      TARGET=$curans
      export TARGET
   else
      if (chkdir $TARGET); then
         exit 0
      fi
   fi
   if [ ".$SRCDIR" = "." ]; then
      SRCDIR=`\cd ../..; pwd`
      export SRCDIR
   fi
   echo "var target $TARGET" >> $ITMPDIR/InstEnv
   echo "var srcdir $SRCDIR" >> $ITMPDIR/InstEnv
elif [ $media = "floppy" ]; then
   echo "Floppy disk installation not currently available."
   cleanup
   exit 1
else
   echo "Unknown media type $media."
   cleanup
   exit 1
fi

echo

if [ $verbose -ne 0 ]; then
   echo ">>> Installation source directory is $SRCDIR."
   echo ">>> Destination directory is $TARGET."
fi

# The installation manifest contains a log of previous sessions. It records what is
# installed, and when.

inst_manifest=$TARGET/SystemFiles/Installation/SystemResources/Manifests/installation

if [ -f $inst_manifest ]; then
   printm V30Found $TARGET
   cp $inst_manifest $ITMPDIR/InstallManifest
elif [ -f $TARGET/.install-manifest ]; then
   printm PartialFound $TARGET
   curans="x"
   while [ .$curans != .c -a .$curans != .a ]; do
      promptname=PartialFound; defanswer=c; . printp;
   done
   if [ .$curans = .a ] ; then
       cleanup
       exit 1
   fi
   cp $TARGET/.install-manifest  $ITMPDIR/InstallManifest
else
   echo " " > $ITMPDIR/InstallManifest
fi

# Initialize installer

awk -f $utils/mmtoiv.awk  $ITMPDIR/InstallManifest > $ITMPDIR/InitInstall

. $ITMPDIR/InitInstall

# Initialize man page stuff

# Add the option to put man pages in any section

if [ .$MANDIR = . ]; then
   MANDIR=/usr/man/man1
fi

if [ .$MANCP = . ]; then
   MANCP="cpz"
fi

echo "var mandir $MANDIR" >> $ITMPDIR/InstEnv
echo "var mancp $MANCP" >> $ITMPDIR/InstEnv

# write the from line to the installation manifest (you cannot do this
# until after the variables are read)

cat $media_manifest | awk -f $utils/mmtofl.awk >> $ITMPDIR/InstallManifest

# Get the architecture list

cat $media_manifest | awk -f $utils/getarch.awk > $ITMPDIR/ArchList

if [ $install_type = "X" ]; then
   if [ `grep -c "^$INSTALLARCH\$" $ITMPDIR/ArchList` -ne 1 ]; then
      install_type="c"
      export install_type
   fi
fi

# Ask for installation type

if [ $install_type = "X" ]; then
   echo
   promptname=InstallType; defanswer=${definst_type:-"d"}; . printp;
   
   while ( [ ".$curans" != ".d" ] && [ ".$curans" != ".c" ] ); do
      cat $textres/DefaultHelp
      echo " "
      promptname=InstallType; defanswer=d; . printp;
   done
   echo
   
   if [ $curans = "d" ] ; then
      install_type="a"
      export install_type
      savev definst_type d
   fi
   if [ $curans = "c" ] ; then
      install_type="c"
      export install_type
      savev definst_type c
   fi
fi

# Form the install template (sort of a to-do list) depending on
# the install type. This template is realized as a set of installer
# choices in the temporary file InstallTemplate.

# Install type p allows only a password to be set 

if [ $install_type = "p" ]; then
   selected_arch=$INSTALLARCH
   export selected_arch
   skippw=0
   savev defarch $selected_arch
   echo "install CommonPassword" > $ITMPDIR/InstallTemplate
fi

# Do not prompt for password if -nopass is selected.

if [ $skippw -eq 1 ]; then
   touch $ITMPDIR/PassPrompt
fi

# install type a. Generate install template from predefined list.

if [ $install_type = "a" ]; then

   if [ .$selected_arch = . ]; then
      selected_arch=$INSTALLARCH
      export selected_arch
   fi

   (echo "arch $selected_arch"; cat $media_manifest) | awk -f $utils/mmtoit.awk > $ITMPDIR/InstallTemplate
   # supplemental prompts for default installation
   buildmathpass $selected_arch
   if [ -f $ITMPDIR/AbortInstall ]; then
      cleanup
      exit 1
   fi
   . cmdprompt
fi

# install type c. Prompt user for all aspects of template

if [ $install_type = "c" ]; then
   printm CustomGreeting
   cat $ITMPDIR/ArchList
   echo
   promptname=CustomGreeting; defanswer=${defarch:-"$INSTALLARCH"}; . printp;
   while [ `grep -c "^$curans\$" $ITMPDIR/ArchList` -ne 1 ]; do
        printm NoSystemType $curans
        promptname=CustomGreeting; defanswer=${defarch:-"$INSTALLARCH"}; . printp;
   done

   selected_arch=$curans
   export selected_arch
   savev defarch $selected_arch

   (echo "selectedarch $selected_arch"; cat $media_manifest) | awk -f $utils/getprod.awk > $ITMPDIR/CompList

   # CompList contains a one line listing of each installable thing
   # from the media.

   if [ $debug -ne 0 ]; then
      echo "Debug: Current component list is:"
      echo
      cat $ITMPDIR/CompList
      echo " "
   fi

   # Sanity check. Make certain that component manifests and help exists

   if [ $checkfiles -ne 0 ]; then
      if ( checkfiles $textres $ITMPDIR/CompList ); then
         printm Inconsistency $inst_manifest
         cleanup
         exit 1
      fi
   fi

   if [ $checkfiles -ne 0 ]; then
      if ( checkfiles $comp_manifests $ITMPDIR/CompList ); then
         printm Inconsistency $inst_manifest
         cleanup
         exit 1
      fi
   fi

   echo " " > $ITMPDIR/InstallTemplate

   # The title for each component is in text resources along with the
   # help text. Why? So it can be translated, of course!

   if [ ! -f $ITMPDIR/CompSelect ]; then
      echo "" > $ITMPDIR/CompSelect
   fi

   (echo "prepend cat $textres/"; cat $ITMPDIR/CompList) | awk -f $utils/prepend.awk | sh > $ITMPDIR/NCompHelp
   (echo "instarch $selected_arch"; cat $ITMPDIR/NCompHelp) | awk -f $utils/titletab.awk > $ITMPDIR/TitleTable
 
   lastlink="" 
   curans="x"

   cat $ITMPDIR/TitleTable $ITMPDIR/InstallTemplate $textres/CompMenu | awk -f $utils/compmenu.awk
   promptname=ComponentSpec; defanswer=""; . printp;

   echo $curans | awk -f $utils/parse.awk >> $ITMPDIR/CompSelect

   echo
   if [ `echo $curans | awk -f $utils/linkchk.awk` = "error" ]; then
   printm CustomError
   exit 1
   elif [ `echo $curans | awk -f $utils/linkchk.awk` = "link" ]; then
      printm SymbolicLinks
      linktext=""
      while [ ."$linktext" = . ]; do
         promptname=SymbolicLinks; defanswer=""; . printp;
         linktext=$curans
         if [ ! -d "$curans/SystemFiles" ]; then
            printm NoLinkTarget $curans
            promptname=NoLinkTarget; defanswer=c; . printp;
         fi
         if [ ."$curans" = .d ]; then
            linktext=""
         fi
      done 
   fi

   (echo "linktext $linktext"; 
    cat $ITMPDIR/TitleTable $ITMPDIR/InstallTemplate $ITMPDIR/CompSelect) | awk -f $utils/cstoit.awk > $ITMPDIR/InstallTemplate
fi

#  -auto install template logic.
#
#  Any specified installation template takes priority. If no install template
#  is specified, derive it from the installation manifest. If no installation
#  manifest exists, do a default install, assuming default answers to all
#  questions.

if [ $install_type = "A" ]; then
   if [ .$selected_arch = . ]; then
      selected_arch=$INSTALLARCH
      export selected_arch
   fi
   if [ ."$template" = . ]; then
      template="/unlikelytoexist"
   fi
   if [ -f $template ]; then
       cp $template $ITMPDIR/InstallTemplate
   else
      if [ -f $inst_manifest ]; then
         (echo "arch $selected_arch"; cat $media_manifest $inst_manifest) | awk -f $utils/imtoit.awk > $ITMPDIR/InstallTemplate
      else
         (echo "arch $selected_arch"; cat $media_manifest) | awk -f $utils/mmtoit.awk > $ITMPDIR/InstallTemplate
      fi
   fi
   touch $ITMPDIR/PassPrompt
fi

# Fix command directory

if [ -f $ITMPDIR/CommandDir ]; then
   CMDDIR=`cat $ITMPDIR/CommandDir`
   export CMDDIR
fi

echo "var instarch $selected_arch" >> $ITMPDIR/InstEnv

# Turn the install template into a list of components for installation.
# We then pass them all through mergeorder twice to resolve depends issues.

cat $ITMPDIR/InstallTemplate | awk -f $utils/compcl.awk > $ITMPDIR/CompInstall

(echo "prepend cat $comp_manifests/"; cat $ITMPDIR/CompInstall) | 
  awk -f $utils/prepend.awk | sh | awk -f $utils/mergeorder.awk > $ITMPDIR/MergeList.tmp

(echo "prepend cat $comp_manifests/"; cat $ITMPDIR/MergeList.tmp) | 
  awk -f $utils/prepend.awk | sh | awk -f $utils/mergeorder.awk > $ITMPDIR/MergeList

# reverse the order of merge list, combine component manifests

(echo "prepend cat $comp_manifests/"; cat $ITMPDIR/MergeList) |
  awk -f $utils/prepend.awk | sh > $ITMPDIR/CompManifests

if [ $debug -ne 0 ]; then
   echo
   echo ">>> Install template is:"
   cat $ITMPDIR/InstallTemplate
   echo " "
fi

(cat $ITMPDIR/InstallTemplate; 
 cat $ITMPDIR/InstallManifest; 
 cat $media_manifest; 
 cat $ITMPDIR/CompManifests) | awk -f $utils/merge.awk > $ITMPDIR/InstallMethods

if [ $debug -ne 0 ]; then
   echo ">>> Install methods computed as:"
   echo
   cat $ITMPDIR/InstallMethods
   echo
fi

sh $ITMPDIR/InstallMethods pre $verbose 2> $ITMPDIR/Errors

cat $ITMPDIR/Errors | awk '{ print "error " $0 }' >> $ITMPDIR/InstallManifest

if [ $verbose -ne 0 ]; then
   cat $ITMPDIR/Errors
fi

if [ -f $ITMPDIR/AbortInstall ]; then
   cleanup
   exit 1
fi

if [ $install_type = a ] ; then
   printm DefaultBegin $selected_arch
elif [ $install_type = c ] ; then
   printm CustomBegin $selected_arch
fi

if [ $safe -ne 0 ]; then
  printm PrintInstall $ITMPDIR/InstallTemplate
  sh $ITMPDIR/InstallMethods safe $verbose
  exit 0
else
  sh $ITMPDIR/InstallMethods post $verbose
  if [ -d $TARGET/SystemFiles/Installation/SystemResources/Manifests ]; then
     cp $ITMPDIR/InstallManifest $inst_manifest 2> /dev/null
     cp $media_manifest $TARGET/SystemFiles/Installation/SystemResources/Manifests 2> /dev/null
     cp $ITMPDIR/InstallTemplate $TARGET/SystemFiles/Installation/SystemResources/Manifests/template 2> /dev/null
     rm -f $TARGET/.install-manifest
  else
     touch $ITMPDIR/AbortInstall
  fi
fi

if [ -f $ITMPDIR/AbortInstall ]; then
   printm Incomplete
else
   printm Complete
fi
cleanup
exit 0
