#!/bin/sh

# tamarin relies on ghc, haskell-stack, etc.
#   which support x86_64 and aarch64:
#   https://www.haskell.org/ghc/download_ghc_9_10_1.html#binaries
#   https://github.com/commercialhaskell/stack/releases
# on x86_64:
#   easy to install haskell-stack and tamarin via homebrew
#   using "linuxbrew" account so that homebrew avoids compiling from source
# on aarch64:
#   homebrew tries compiling far too many packages,
#   often packages that need patching, so take a different route

umask 022

architecture=`uname -m`

[ -d /home/tamarin ] || useradd -m -s /bin/sh tamarin

sudo -u tamarin sh -c 'cd
  cat > pqconnect_handshake.spthy
' < handshake.spthy

sudo -u tamarin sh -c 'cd
  mkdir -p lib include bin tmp
  ( echo "#X/bin/sh" | tr X "\\041"
    echo "ulimit -n 2048"
    echo "ulimit -n 4096"
    echo "ulimit -n 8192"
    echo "export LD_LIBRARY_PATH=\"\$HOME/lib\""
    echo "export LIBRARY_PATH=\"\$HOME/lib\""
    echo "export CPATH=\"\$HOME/include\""
    echo "export PATH=\"\$HOME/bin:\$HOME/.local/bin:\$PATH\""
  ) > tmp/tamarin
'

if [ "$architecture" = x86_64 ]
then

  [ -d /home/linuxbrew ] || useradd -m -s /bin/sh linuxbrew
  sudo -u linuxbrew sh -c 'cd
    chmod 755 $HOME
    ulimit -n 2048
    ulimit -n 4096
    ulimit -n 8192
    export HOMEBREW_NO_AUTO_UPDATE=1
    [ -d .linuxbrew ] || time git clone https://github.com/Homebrew/brew .linuxbrew
    eval "$(.linuxbrew/bin/brew shellenv)"
    time brew update --force
    chmod -R go-w "$(brew --prefix)/share/zsh"
    time brew install tamarin-prover/tap/tamarin-prover
  '
  sudo -u tamarin sh -c 'cd
    /home/linuxbrew/.linuxbrew/bin/brew shellenv >> tmp/tamarin
  '

elif [ "$architecture" = aarch64 ]
then

  sudo -u tamarin sh -c 'cd
    ulimit -n 2048
    ulimit -n 4096
    ulimit -n 8192

    export LD_LIBRARY_PATH="$HOME/lib"
    export LIBRARY_PATH="$HOME/lib"
    export CPATH="$HOME/include"
    export PATH="$HOME/bin:$HOME/.local/bin:$PATH"

    architecture=`uname -m`

    stack="stack-linux-${architecture}"
    wget -O "$stack.tar.gz" "https://www.stackage.org/stack/linux-${architecture}"
    tar -xf "$stack.tar.gz"
    rm -f $HOME/bin/stack
    ln -s $HOME/stack-*-linux-"${architecture}/stack" $HOME/bin/stack

    [ -d tamarin-prover ] || (
      cd tmp
      rm -rf tamarin-prover
      git clone https://github.com/tamarin-prover/tamarin-prover.git
      mv tamarin-prover $HOME
    )
    ( cd tamarin-prover
      make default
    )

    # maude installation mostly cribbed from https://github.com/maude-lang/Maude/blob/master/INSTALL
    # but a bit more effort here at idempotence etc.

    (
      echo libsigsegv-2.13.tar.gz https://ftp.gnu.org/gnu/libsigsegv/libsigsegv-2.13.tar.gz
      echo gmp-6.3.0.tar.xz https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
      echo buddy-2.4.tar.gz https://github.com/utwente-fmt/buddy/releases/download/v2.4/buddy-2.4.tar.gz
      echo libtecla-1.6.3.tar.gz https://sites.astro.caltech.edu/~mcs/tecla/libtecla-1.6.3.tar.gz
      echo Yices-2.6.4.tar.gz https://github.com/SRI-CSL/yices2/archive/refs/tags/Yices-2.6.4.tar.gz
      echo gperf-3.1.tar.gz https://ftp.gnu.org/pub/gnu/gperf/gperf-3.1.tar.gz
      echo Maude3.5.tar.gz https://github.com/maude-lang/Maude/archive/refs/tags/Maude3.5.tar.gz
    ) | while read target url
    do
      [ -f $target ] || (
        wget -O $target.tmp "$url" &&
          mv $target.tmp $target
      )
      tar -xf $target
    done

    ( cd libsigsegv-2.13
      ./configure CFLAGS="-g -fno-stack-protector -O3" --prefix=$HOME --enable-shared=no
      make -j`nproc`
      # make check
      make install
    )

    ( cd gmp-6.3.0
      ./configure --prefix=$HOME --enable-cxx --enable-fat --enable-shared=yes --build=${architecture}-pc-linux-gnu
      make -j`nproc`
      # make check
      make install
    )

    ( cd buddy-2.4
      ./configure LDFLAGS=-lm CFLAGS="-g -fno-stack-protector -O3" CXXFLAGS="-g -fno-stack-protector -O3" --prefix=$HOME --disable-shared
      make -j`nproc`
      # make check
      make install
    )

    ( cd gperf-3.1
      ./configure --prefix=$HOME
      make
      make install
    )

    ( cd libtecla
      autoupdate
      autoreconf -i
      cp /usr/share/automake-*/config.sub .
      cp /usr/share/automake-*/config.guess .
      ./configure CFLAGS="-g -fno-stack-protector -O3" --prefix=$HOME
      make
      make install
    )

    ( cd yices2-Yices-2.6.4
      autoconf
      ./configure --prefix=$HOME \
      --with-static-gmp=$HOME/lib/libgmp.a --with-static-gmp-include-dir=$HOME/include \
      CFLAGS="-g -fno-stack-protector -O3" LDFLAGS="-L$HOME/lib" CPPFLAGS="-I$HOME/include"
      make -j`nproc`
      # make check
      make install
    )

    ( cd Maude-Maude3.5
      autoreconf -i
      mkdir Opt
      cd Opt
      ../configure --with-yices2=yes --with-cvc4=no --enable-compiler \
      CXXFLAGS="-g -Wall -O3 -fno-stack-protector" CPPFLAGS="-I$HOME/include" LDFLAGS="-L$HOME/lib" \
      GMP_LIBS="$HOME/lib/libgmpxx.a $HOME/lib/libgmp.a"
      make -j`nproc`
      # make check
      cp src/Main/maude $HOME/bin/maude
      cp ../src/Main/prelude.maude $HOME/bin/prelude.maude
    )
  '

else
  echo "[1mThis script supports only x86_64 and aarch64.[0m"
fi

sudo -u tamarin sh -c 'cd
  echo "exec tamarin-prover \"\$@\"" >> tmp/tamarin
  chmod 755 tmp/tamarin
  mv tmp/tamarin tamarin
'
