#!/bin/sh
set -e

ARCH=x86_64
MODSUBDIR=x86_64
USER_PWD="`pwd`"

UsingCMake="no"
UsingCMake="yes"

if test "x${NRNHOME}" = x ; then
  prefix=/Users/runner/work/1/s/build/cmake_install
  exec_prefix=/Users/runner/work/1/s/build/cmake_install
  bindir=${exec_prefix}/bin
  libdir=${exec_prefix}/lib
else
  prefix="$NRNHOME"
  exec_prefix="${prefix}/${ARCH}"
  #bindir="${prefix}/${ARCH}/bin"
  #libdir="${prefix}/${ARCH}/lib"
  bindir="${prefix}/bin"
  libdir="${prefix}/lib"
fi

if [ -z ${CNRNHOME+x} ]; then
  # CNRNHOME wasn't set, use the install prefix
  cnrn_prefix=
else
  cnrn_prefix="${CNRNHOME}"
fi

if test "${NRNHOME_EXEC}" != "" ; then
  exec_prefix="${NRNHOME_EXEC}"
  bindir="${exec_prefix}/bin"
  libdir="${exec_prefix}/lib"
fi

# Besides NRNHOME, one may set NRNBIN to override the default location of user binaries
if test "x$NRNBIN" = "x"; then
  NRNBIN=$bindir
fi

export prefix
export bindir
export libdir

MAKEFILEDIR="${bindir}"

if command -v xcrun; then
    export SDKROOT=`xcrun --sdk macosx --show-sdk-path`
    export MACOSX_DEPLOYMENT_TARGET="10.9"
    if [ -z "${MACOSX_DEPLOYMENT_TARGET}" ]; then
        unset MACOSX_DEPLOYMENT_TARGET
    fi
fi

LinkCoreNEURON=false
if [ "$1" = "-coreneuron" ] ; then
      LinkCoreNEURON=true
      shift
fi

UserINCFLAGS=""
if [ "$1" = "-incflags" ] ; then
      UserINCFLAGS="$2"
      shift
      shift
fi

UserLDFLAGS=""
if [ "$1" = "-loadflags" ] ; then
       UserLDFLAGS="$2"
       shift
       shift
fi

pwd

# Mod file paths may contain spaces which make variable lists of those
# hard to manage as space is the item separator. Furthermore, when a
# path is used, sometimes the spaces must be escaped (eg. a Makefile
# dependency pattern, and sometimes it is more useful for readability to
# enclose the path in "". To work around this issue, when creating a list
# of paths, translate the spaces for each item to +++ and after retrieval
# of an item, retranslate back to either a space or an escaped space.
# Only do this for cmake

hide_spaces() {
  echo "$1" | sed 's/ /+++/g'
}
unhide_spaces() {
  echo "$1" | sed 's/+++/ /g'
}
escape_spaces() {
  echo "$1" | sed 's/+++/\\ /g'
}

# files is the complete list of mod files to process
files=""
#incs=""
if test $# -gt 0 ; then
  for i in "$@" ; do
    i_hide=`hide_spaces "$i"`
    if test -d "$i" ; then
      set +e
      if test "$UsingCMake" = "yes" ; then
        for j in $(cd "$i"; unset LC_ALL; ls *.mod) ; do
          files="$files $i_hide/$j"
        done
      else
        files="$files $(unset LC_ALL; ls $i/*.mod)"
        incs="$incs $(unset LC_ALL; ls $i/*.inc)"
      fi
      set -e
    else
      if test "$UsingCMake" = "yes" ; then
        if test -e "$i" -o -e "$i.mod" ; then
          files="$files $i_hide"
        else
          echo "Arg Error: \"$i\" is not a folder or mod file name or prefix"

          echo ""
          echo -n "  Mod file, folder args:"
          for j in "$@" ; do
            echo -n " \"$j\""
          done
          echo ""

          exit 1
        fi
      else
        files="$files $i"
      fi
    fi
  done
else
  # Unset LC_ALL for consistent mod order
  files=$(unset LC_ALL; ls *.mod)
fi

files=`echo "$files" | sed 's/^ *//'`

base_names=""
for i in $files ; do
  base_names="$base_names `basename $i .mod`"
done

if test "$UsingCMake" = "yes" ; then
  echo -n "Mod files:"
  for i in $files ; do
    base_name=`basename "$i" .mod`
    dir_name=`dirname "$i"`
    echo -n " \"`unhide_spaces $dir_name`/$base_name.mod\""
  done
  echo ""
  echo ""
fi

if [ ! -d $MODSUBDIR ] ; then
  echo "Creating $MODSUBDIR directory for .o files."
  echo
  mkdir $MODSUBDIR
fi

files=`echo "$files" | sed 's/\.mod//g'`

if test "$files" = '*' ; then
  files=""
fi

cd $MODSUBDIR
mdir="`pwd`"

if test "$UsingCMake" = "yes" ; then
  # construct file to be included by makefile to specify mod to c rule when
  # executed in $MODSUBDIR (child folder of launch location folder)
  MODMAKE=makemod2c_inc
  echo "" > $MODMAKE
  for i in $files ; do
    case "$i" in
      /*) f=$i;; # absolute, fine as is
      *)  f=../$i;; # relative
    esac
    base_name="`basename $f`"
    dir_name="`dirname $f`"
    # Note: indentation for shell lines in make rules must be a tab
    echo "\
./$base_name.c: `escape_spaces "$f.mod"`
	@printf \" -> \$(C_GREEN)NMODL\$(C_RESET) \$<\\\n\"
	(cd \"`unhide_spaces $dir_name`\"; MODLUNIT=\$(NRNUNITS) \$(NOCMODL) $base_name.mod -o \"$mdir\")

./$base_name.o: ./$base_name.c
	@printf \" -> \$(C_GREEN)Compiling\$(C_RESET) \$<\\\n\"
	\$(COMPILE) -I\"`unhide_spaces $dir_name`\" \$(INCLUDES) -fPIC -c \$< -o \$@
" >> $MODMAKE
  done
  if test "$nrnivmodl_cfiles" != "" ; then
    # I find it very difficult to construct shell variables which are
    # space separated lists of items containing spaces. So, for a cmake build,
    # the nrnivmodl_cfiles variable is required to be a ';' separated list
    # of c files which may contain spaces.
    # Save the Internal Field Separator and interpret variables as ';'
    # separated list of items (which may contain spaces). Restore after
    # processing nrnivmodl_cfiles.
    ifs="$IFS"
    IFS=';'
    for i in $nrnivmodl_cfiles ; do
      i_hide=`hide_spaces "$i"`
      case "$i_hide" in
        /*) f=$i_hide;; # absolute, fine as is
        *)  f=../$i_hide;; # relative
      esac
      base_name="`basename $f .c`"
      dir_name="`dirname $f`"
      echo "\
./$base_name.o: `escape_spaces "$f"`
	@printf \" -> \$(C_GREEN)Compiling\$(C_RESET) \$<\\\n\"
	(cd \"`unhide_spaces $dir_name`\"; \$(COMPILE) \$(INCLUDES) -fPIC -c $base_name.c -o \"$mdir/$base_name.o\")
" >> $MODMAKE
    done
    IFS="$ifs"
  fi
else
  for i in $files; do
       rm -f "`basename $i`".mod
       ln -s ../$i.mod .
  done

  if test "$incs" != "" ; then
       for i in $incs ; do
               rm -f "`basename $i`"
               ln -s ../$i .
       done
  fi

  for i in $nrnivmodl_cfiles; do
       rm -f "$i"
       ln -s "../$i" .
  done
fi

COBJS=
MODOBJS=
if [ `echo "\n"` ] ; then
  newline="\n"
else
  newline="\\\\n"
fi

echo '#include <stdio.h>
#include "hocdec.h"
extern int nrnmpi_myid;
extern int nrn_nobanner_;
' > mod_func.c
for i in $base_names ; do
  echo 'extern void _'$i'_reg(void);'
done >> mod_func.c
echo '
void modl_reg(){
  if (!nrn_nobanner_) if (nrnmpi_myid < 1) {
    fprintf(stderr, "Additional mechanisms from files'$newline'");
' >> mod_func.c

for i in $files
do
  echo '    fprintf(stderr," \"'`unhide_spaces "$i"`'.mod\"");'
done >>mod_func.c

echo '    fprintf(stderr, "'$newline'");
  }' >>mod_func.c

for i in $base_names; do
  echo '  _'$i'_reg();'
  MODOBJS="$MODOBJS ./$i.o"
  #MODOBJS="$MODOBJS $i.o"
done >> mod_func.c

echo "}" >> mod_func.c

if test -n "$nrnivmodl_cfiles" ; then
  if test "$UsingCMake" = "yes" ; then
    sp=""
    COBJS=""
    ifs="$IFS"
    IFS=';'
    for i in $nrnivmodl_cfiles ; do
      base_name=`basename "$i" .c`
      COBJS="${COBJS}${sp}./${base_name}.o"
      sp=" "
    done
    IFS="$ifs"
  else
    COBJS=`echo "$nrnivmodl_cfiles" | sed 's/\.c/.o/g'`
  fi
fi
echo "COBJS='$COBJS'"

# call nrnivmodl-core if CoreNEURON is enabled and requested via CLI
UsingCoreNEURON="no"
#UsingCoreNEURON="yes"
if [ "$LinkCoreNEURON" = true ] ; then
  if [ "$UsingCMake" = "yes" ] ; then
    if [ "$UsingCoreNEURON" = "yes" ] ; then
      cd $USER_PWD
      args=""
      # pass the nrnivmodl file args to nrnivmodl-core (with spaces escaped)
      for i in "$@"; do
        j=`hide_spaces "$i"`
        j=`escape_spaces "$j"`
        args="$args $j"
      done
      "${cnrn_prefix}/bin/nrnivmodl-core" $args
      cd $MODSUBDIR
    else
      printf "ERROR : CoreNEURON support is not enabled!\n"
      exit 1
    fi
  else
    printf "ERROR : CoreNEURON is not compatible with autotools, build with CMake build system!\n"
    exit 1
  fi
fi

#make -j 4 -f "${MAKEFILEDIR}/nrnmech_makefile" "ROOT=${prefix}" "MODOBJFILES=$MODOBJS" "COBJFILES=$COBJS" "UserLDFLAGS=$UserLDFLAGS" "UserINCFLAGS=$UserINCFLAGS" "LinkCoreNEURON=$LinkCoreNEURON" special &&
##make -j 4 -f "${MAKEFILEDIR}/nrniv_makefile" "ROOT=${prefix}" "MODOBJFILES=$MODOBJS" "COBJFILES=$COBJS" "UserLDFLAGS=$UserLDFLAGS" "UserINCFLAGS=$UserINCFLAGS" special &&
#  echo "Successfully created $MODSUBDIR/special"

MODLO=`echo "$MODOBJS" | sed 's/\.o/.lo/g'`
CLO=`echo "$COBJS" | sed 's/\.o/.lo/g'`
if test "${mdir}" = "${prefix}/share/nrn/demo/release/powerpc" ; then
  mdir='${NRNHOME}'/share/nrn/demo/release/${MODSUBDIR}
fi
#make -j 4 -f "$MAKEFILEDIR/nrnmech_makefile" "ROOT=${prefix}" "MODOBJFILES=$MODLO" "COBJFILES=$CLO" "UserLDFLAGS=$UserLDFLAGS" "UserINCFLAGS=$UserINCFLAGS" libnrnmech.la
make -j 4 -f "$MAKEFILEDIR/nrnmech_makefile" "ROOT=${prefix}" "MODOBJFILES=$MODOBJS" "COBJFILES=$COBJS" "UserLDFLAGS=$UserLDFLAGS" "UserINCFLAGS=$UserINCFLAGS" "LinkCoreNEURON=$LinkCoreNEURON" mech_lib_shared VERBOSE=1
  echo '#!/bin/sh
if test "x${NRNHOME}" = "x" ; then
    NRNHOME='"\"${prefix}\""'
fi
if test "${NEURONHOME}" = "" ; then
    NEURONHOME=${NRNHOME}/share/nrn
    export NEURONHOME
fi
if test "x${NRNBIN}" = "x" ; then
    NRNBIN='"\"${NRNBIN}\""'
fi
if test "" = "yes" ; then
    NRNIV="${NRNBIN}/nrniv.app/Contents/MacOS/nrniv"
else
    NRNIV="${NRNBIN}/nrniv"
fi
"${NRNIV}"'" -dll \"${mdir}/.libs/libnrnmech.so\" \"\$@\"" > special &&
  chmod 755 special &&
  echo "Successfully created $MODSUBDIR/special"

if false ; then
#if false ; then
#if false ; then
  false #for empty if block
fi
