#!/bin/sh

#
# Note: When adding make options to this script, ensure that the source still
#       compiles without those options! (and just with GNUstep.sh being
#       sourced)
#       We do not want to force people to run configure.
#

# ******************** variables ****************

TOPDIR="$(cd `dirname $0`; pwd)"

# we ensure that the configure script is run from TOPDIR
cd "${TOPDIR}"

CFG_ARGS="$0 $1 $2 $3 $4 $5 $6 $7 $8 $9"

ARG_BEQUIET=0
ARG_NOCREATE=0
ARG_PREFIX=""
ARG_GSMAKE=`gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null`
ARG_CFGMAKE="$PWD/config.make"
ARG_CFGSSL="auto"
ARG_WITH_DEBUG=1
ARG_WITH_STRIP=0
ARG_ENABLE_SAML2=0
ARG_ENABLE_MFA=0
ARG_ENABLE_SODIUM=1
ARG_WITH_LDAP_CONFIG=0

GNUSTEP_INSTALLATION_DOMAIN="LOCAL"

DARG_GNUSTEP_SH="$ARG_GSMAKE/GNUstep.sh"

# detect GNU make, needed at least on *BSD
make -v 2>/dev/null | grep GNU >/dev/null 2>/dev/null
if [ $? -eq 0 ];then
  MAKE=make
else
  MAKE=gmake
fi

# hostname(1) on some systems may not know the -f parameter
hostname -f 2>/dev/null >/dev/null
if [ $? -eq 0 ];then
  HOSTNAME=`hostname -f`
else
  HOSTNAME=`hostname`
fi


NGSTREAMS_DIR="./sope-core/NGStreams"
LINK_SYSLIBDIRS="-L/usr/local/pgsql/lib -L/usr/local/lib -L/usr/lib"

# ******************** usage ********************

usage() {
  cat <<_ACEOF
\`configure' configures a GNUstep-make based sourcetree for installation.

Usage: $0 [OPTION]...

Note: You do not need to configure this source tree, as another option
      just ensure that the GNUstep.sh of your GNUstep make installation
      is properly sourced prior running make.

Configuration:
  -h, --help              display this help and exit
  -q, --quiet, --silent   do not print \`checking...' messages
  -n, --no-create         do not create output files

Installation directories:
  --prefix=PREFIX	  install files in PREFIX [/usr/local]
  --gsmake=PATH           path to gnustep-make tree
  --configmake=PATH       path to the config file being created
  --enable-debug          turn on debugging and compile time warnings
  --enable-strip          turn on stripping of debug symbols
  --with-ssl=SSL          specify ssl library (none, ssl, gnutls, auto) [auto]
  --enable-saml2          enable support for SAML2 authentication (requires liblasso)
  --enable-mfa            enable multi-factor authentication (requires liboath)
  --disable-sodium        disable building with libsodium (will disable argon2 password schemes)
  --enable-ldap-config    enable LDAP based configuration of SOGo

_ACEOF

  exit 0;
}

# ******************** running ********************

printParas() {
  echo "Configuration:"
  if test $ARG_BEQUIET  = 1; then echo "  will be quite.";  fi
  if test $ARG_NOCREATE = 1; then echo "  won't create files"; fi

  if test $ARG_WITH_DEBUG = 1; then 
    echo "  debug:  yes";
  else
    echo "  debug:  no";
  fi
  if test $ARG_WITH_STRIP = 1; then 
    echo "  strip:  yes";
  else
    echo "  strip:  no";
  fi
  if test $ARG_ENABLE_SAML2 = 1; then 
    echo "  saml2 support:  yes";
  else
    echo "  saml2 support:  no";
  fi
  if test $ARG_ENABLE_MFA = 1; then
    echo "  mfa support:  yes";
  else
    echo "  mfa support:  no";
  fi
  if test $ARG_ENABLE_SODIUM = 1; then
    echo "  argon2 support:  yes";
  else
    echo "  argon2 support:  no";
  fi
  if test $ARG_WITH_LDAP_CONFIG = 1; then
    echo "  ldap-based configuration:  yes";
  else
    echo "  ldap-based configuration:  no";
  fi
  
  echo "  prefix: $ARG_PREFIX"
  echo "  gstep:  $ARG_GSMAKE"
  echo "  config: $ARG_CFGMAKE"
  echo "  script: $DARG_GNUSTEP_SH"
  echo ""
}

validateGNUstepArgs() {
  # GNUstep make
  if test "x$ARG_GSMAKE" = "x"; then
    if test -f $HOME/OGoRoot/Library/Makefiles/GNUstep.sh; then
      ARG_GSMAKE="$HOME/OGoRoot/Library/Makefiles/"
    elif test -f $HOME/GNUstep/Library/Makefiles/GNUstep.sh; then
      ARG_GSMAKE="$HOME/GNUstep/Library/Makefiles/"
    elif test -f /usr/GNUstep/System/Library/Makefiles/GNUstep.sh; then
      ARG_GSMAKE="/usr/GNUstep/System/Library/Makefiles/"
    elif test -f /usr/share/GNUstep/Makefiles/GNUstep.sh; then
      ARG_GSMAKE="/usr/share/GNUstep/Makefiles/"
    elif test -f $GNUSTEP_MAKEFILES/GNUstep.sh; then
      ARG_GSMAKE="$GNUSTEP_MAKEFILES/"
    else
      echo "error: please specify a GNUstep make tree!"
      exit 1
    fi
    DARG_GNUSTEP_SH="$ARG_GSMAKE/GNUstep.sh"
  elif test -d $ARG_GSMAKE; then
    if test -f $ARG_GSMAKE/GNUstep.sh; then
      DARG_GNUSTEP_SH="$ARG_GSMAKE/GNUstep.sh"
    elif test -f $ARG_GSMAKE/Library/Makefiles/GNUstep.sh; then
      ARG_GSMAKE="$ARG_GSMAKE/Library/Makefiles"
      DARG_GNUSTEP_SH="$ARG_GSMAKE/GNUstep.sh"
    else
      echo "error: specified directory contains no GNUstep.sh: $ARG_GSMAKE"
      exit 1
    fi
  else
    echo "error: specified GNUstep make tree does not exist: $ARG_GSMAKE"
    exit 1
  fi
}

validateArgs() {
  # validate prefix (could be better?)
  case "x$ARG_PREFIX" in
    "x")
          ARG_PREFIX="$GNUSTEP_LOCAL_ROOT"
	  GNUSTEP_INSTALLATION_DOMAIN="LOCAL"
          if test $ARG_BEQUIET != 1; then
	      echo "Note: will install in GNUSTEP_LOCAL_ROOT: $ARG_PREFIX"
	      echo ""
	  fi
	;;
    "x$GNUSTEP_USER_ROOT")
	  GNUSTEP_INSTALLATION_DOMAIN="USER"
          if test $ARG_BEQUIET != 1; then
	      echo "Note: will install in GNUSTEP_USER_ROOT: $ARG_PREFIX"
	      echo ""
	  fi
	;;
    "x$GNUSTEP_LOCAL_ROOT")
	  GNUSTEP_INSTALLATION_DOMAIN="LOCAL"
          if test $ARG_BEQUIET != 1; then
	      echo "Note: will install in GNUSTEP_LOCAL_ROOT: $ARG_PREFIX"
	      echo ""
	  fi
	;;
    "x$GNUSTEP_NETWORK_ROOT")
	  GNUSTEP_INSTALLATION_DOMAIN="NETWORK"
          if test $ARG_BEQUIET != 1; then
	      echo "Note: will install in GNUSTEP_NETWORK_ROOT: $ARG_PREFIX"
	      echo ""
	  fi
	;;
    "x$GNUSTEP_SYSTEM_ROOT")
	  GNUSTEP_INSTALLATION_DOMAIN="SYSTEM"
          if test $ARG_BEQUIET != 1; then
	      echo "Note: will install in GNUSTEP_SYSTEM_ROOT: $ARG_PREFIX"
	      echo ""
	  fi
	;;
    *)
	  echo "error: specified prefix is not a GNUstep root: '$ARG_PREFIX'"
	  exit 1
	;;
  esac
}

printGNUstepSetup() {
  echo "GNUstep environment:"
  echo "  system: ${GNUSTEP_SYSTEM_ROOT}"
  echo "  local:  ${GNUSTEP_LOCAL_ROOT}"
  echo "  user:   ${GNUSTEP_USER_ROOT}"
  echo "  path:   ${GNUSTEP_PATHLIST}"
  echo "  flat:   ${GNUSTEP_FLATTENED}"
  echo "  arch:   ${GNUSTEP_HOST}"
  echo "  combo:  ${LIBRARY_COMBO}"
  echo ""
}

cfgwrite() {
  echo "$1" >> "${ARG_CFGMAKE}"
}

genConfigMake() {
  # we ignore the following vars also patches by gstep-make:
  #   PATH
  #   DYLD_LIBRARY_PATH
  #   GUILE_LOAD_PATH
  #   CLASSPATH
  
  if test $ARG_BEQUIET != 1; then
    echo "creating: $ARG_CFGMAKE"
  fi
  
  echo "# GNUstep environment configuration" > "${ARG_CFGMAKE}"

  cfgwrite "#   created by: '$CFG_ARGS'"
  cfgwrite ""
  
  cfgwrite "# Note: you can override any option as a 'make' parameter, eg:"
  cfgwrite "#         $MAKE debug=yes"
  cfgwrite ""

  TOPDIR_CFGWRITE=`echo ${TOPDIR} | sed 's/ /\\\ /g'`
  cfgwrite "TOPDIR:=${TOPDIR_CFGWRITE}"
  cfgwrite ""

  cfgwrite "NEEDS_GUI=no"

  # SOPE version
  cfgwrite "SOPE_MAJOR_VERSION=4"
  cfgwrite "SOPE_MINOR_VERSION=9"

  # Languages
  cfgwrite "SOGO_LANGUAGES=Arabic Basque Bosnian BrazilianPortuguese Bulgarian Catalan ChineseChina ChineseTaiwan Croatian Czech Danish Dutch English Finnish French Galician German Greek Hebrew Hungarian Icelandic Indonesian Italian Japanese Kazakh Korean Latvian Lithuanian Macedonian Montenegrin NorwegianBokmal NorwegianNynorsk Polish Portuguese Romanian Russian Serbian SerbianLatin Slovak Slovenian SpanishArgentina SpanishSpain Swedish Thai TurkishTurkey Ukrainian Welsh"
  
  #cfgwrite "# print on the cmdline that this file is being used"
  #cfgwrite "all :: "
  #cfgwrite "	@echo Local GNUstep config.make is active"
  #cfgwrite ""

  if test $ARG_WITH_DEBUG = 1; then
    cfgwrite "# configured to produce debugging code";
    cfgwrite "debug:=yes"
  else
    cfgwrite "# configured to produce non-debugging code";
    cfgwrite "debug:=no"
  fi
  cfgwrite ""
  UNAME=`uname`
  if [ "X${UNAME}" = "XLinux" ];then
    UNAME=`uname -m`
    if [ ${UNAME} = x86_64 -o ${UNAME} = sparc64 -o ${UNAME} = ppc64 ];then
      cfgwrite "CGS_LIBDIR_NAME:=lib64"
    else
      cfgwrite "CGS_LIBDIR_NAME:=lib"
    fi
  else
    cfgwrite "CGS_LIBDIR_NAME:=lib"
  fi

  cfgwrite "HOSTNAME=${HOSTNAME}"
  cfgwrite "SOGO_SYSLIBDIR=\${GNUSTEP_SYSTEM_LIBRARIES}"
  cfgwrite "SOGO_LIBDIR=\${GNUSTEP_LIBRARY}/SOGo"
  cfgwrite "SOGO_TEMPLATESDIR=\${SOGO_LIBDIR}/Templates"
  cfgwrite "SOGO_WEBSERVERRESOURCESDIR=\${SOGO_LIBDIR}/WebServerResources"
  cfgwrite "SOGO_TOOLS=\${GNUSTEP_TOOLS}"
  cfgwrite "SOGO_ADMIN_TOOLS=\${GNUSTEP_ADMIN_TOOLS}"
  cfgwrite "SOPE_SAXMAPPINGS=\${GNUSTEP_LIBRARY}/SaxMappings"
  cfgwrite "SOPE_SAXDRIVERS=\${GNUSTEP_LIBRARY}/SaxDrivers-\${SOPE_MAJOR_VERSION}.\${SOPE_MINOR_VERSION}"
  cfgwrite "SOPE_WOXBUILDERS=\${GNUSTEP_LIBRARY}/WOxElemBuilders-\${SOPE_MAJOR_VERSION}.\${SOPE_MINOR_VERSION}"
  cfgwrite "SOGO_TYPEMODELS=\${GNUSTEP_LIBRARY}/OCSTypeModels"

  if test $ARG_WITH_STRIP = 1; then
    cfgwrite "# configured to produce stripped code";
    cfgwrite "strip:=yes"
  else
    cfgwrite "# configured not to strip code";
    cfgwrite "strip:=no"
  fi
  cfgwrite ""

  cfgwrite "# enforce shared libraries";
  cfgwrite "shared:=yes"
  cfgwrite ""

  cfgwrite "# GNUstep environment variables:";
  cfgwrite "GNUSTEP_INSTALLATION_DOMAIN=$GNUSTEP_INSTALLATION_DOMAIN"
  for i in `env | grep ^GNUSTEP_ | sort`; do
    MAKE_ASSI="`echo $i | sed s/=/:=/`"
    cfgwrite "${MAKE_ASSI}";
  done
  cfgwrite "LIBRARY_COMBO=$LIBRARY_COMBO"
  cfgwrite ""

  if test $ARG_ENABLE_SAML2 = 1; then
      cfgwrite "ADDITIONAL_CPPFLAGS += -DSAML2_CONFIG=1"
      cfgwrite "saml2_config:=yes"
  fi

  if test $ARG_ENABLE_MFA = 1; then
      cfgwrite "ADDITIONAL_CPPFLAGS += -DMFA_CONFIG=1"
      cfgwrite "mfa_config:=yes"
  fi

  if test $ARG_WITH_LDAP_CONFIG = 1; then
      cfgwrite "ADDITIONAL_CPPFLAGS += -DLDAP_CONFIG=1"
      cfgwrite "ldap_config:=yes"
  fi

  cfgwrite "include \$(TOPDIR)/general.make"
}

checkLinking() {
  # library-name => $1, type => $2
  local oldpwd="${PWD}"
  local tmpdir=".configure-test-$$"

  mkdir $tmpdir
  cd $tmpdir
  cat > dummytool.c <<EOF
#include <stdio.h>

int main(int argc, char **argv) {
  return 0;
}
EOF
  
  OLDLIBS=$LIBS
  for LIB in $1;do
    LIBS="$LIBS -l${LIB}"
  done

  tmpmake="GNUmakefile"
  echo  >$tmpmake "-include ../config.make"
  echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/common.make"
  echo >>$tmpmake "CTOOL_NAME           := linktest"
  echo >>$tmpmake "linktest_C_FILES := dummytool.c"
  echo >>$tmpmake "ifeq (\$(findstring openbsd, \$(GNUSTEP_HOST_OS)), openbsd)"
  echo >>$tmpmake "linktest_TOOL_LIBS  += $LIBS -liconv"
  echo >>$tmpmake "else"
  echo >>$tmpmake "linktest_TOOL_LIBS  += $LIBS"
  echo >>$tmpmake "endif"
  echo >>$tmpmake "SYSTEM_LIB_DIR += \$(CONFIGURE_SYSTEM_LIB_DIR)"
  echo >>$tmpmake "SYSTEM_LIB_DIR      += ${LINK_SYSLIBDIRS}"
  echo >>$tmpmake "include \$(GNUSTEP_MAKEFILES)/ctool.make"
  
  $MAKE -s messages=yes -f $tmpmake linktest >out.log 2>err.log
  LINK_RESULT=$?

  if test $LINK_RESULT = 0; then
    echo "$2 library found: $1"
    cfgwrite "HAS_LIBRARY_$1=yes"
  else
    if test "x$2" = "xrequired"; then
      echo "failed to link $2 library: $1"
      rm ../config.make
      exit 1
    else
      echo "failed to link $2 library: $1"
      cfgwrite "HAS_LIBRARY_$1=no"
      LIBS=$OLDLIBS
    fi
  fi
  
  cd "${oldpwd}"
  rm -rf $tmpdir

  return $LINK_RESULT
}

checkDependencies() {
  cfgwrite "BASE_LIBS := `gnustep-config --base-libs` -lzip -lytnef"
  if test "x$ARG_ENABLE_SAML2" = "x1"; then
      checkLinking "lasso"   required;
      if test $? = 0; then
          lasso_cflags="`pkg-config lasso --cflags`"
          cfgwrite "LASSO_CFLAGS := $lasso_cflags"
          lasso_libs="`pkg-config lasso --libs` `pkg-config gobject-2.0 --libs`"
          cfgwrite "LASSO_LIBS := $lasso_libs"
      fi;
  fi
  if test "x$ARG_ENABLE_MFA" = "x1"; then
      checkLinking "oath"   required;
      if test $? = 0; then
          cfgwrite "MFA_LIBS := -loath"
      fi;
  fi
  if test "x$ARG_ENABLE_SODIUM" = "x1"; then
    checkLinking "sodium"   required;
  fi
  if test "x$ARG_CFGSSL" = "xauto"; then
      checkLinking "ssl"     optional;
      if test $? != 0; then
          checkLinking "gnutls"  optional;
      fi;
  elif test "x$ARG_CFGSSL" = "xssl"; then
      checkLinking "ssl"     required;
  elif test "x$ARG_CFGSSL" = "xgnutls"; then
      checkLinking "gnutls"  required;
  fi
}

runIt() {
  DISABLED_STRIPPING=0
  if test $ARG_WITH_DEBUG = 1 && test $ARG_WITH_STRIP = 1; then
    DISABLED_STRIPPING=1;
    ARG_WITH_STRIP=0;
  fi

  if test $ARG_BEQUIET != 1; then
    if test $DISABLED_STRIPPING = 1; then
	echo "Note: Disabling stripping of symbols since debug is enabled";
    fi
    printParas;
  fi

  if test $ARG_NOCREATE = 1; then 
    if test $ARG_BEQUIET != 1; then
      echo "not creating the config file ...";
    fi
  else
    genConfigMake;
    checkDependencies;
    
    if test -x $NGSTREAMS_DIR/configure; then
      if test $ARG_BEQUIET != 1; then
        echo -n "configuring NGStreams library .."
        old="$PWD"
        cd $NGSTREAMS_DIR
        ./configure >$old/config-NGStreams.log
        cd $old
        echo ".. done (log in config-NGStreams.log)."
      fi
    fi
  fi
}

# ******************** options ********************

extractFuncValue() {
  VALUE="`echo "$1" | sed "s/[^=]*=//g"`"
}

processOption() {
  case "x$1" in
    "x--help"|"x-h")
	usage;
	;;
    "x--quiet"|"x--silent"|"x-q") ARG_BEQUIET=1;  ;;
    "x--no-create"|"x-n")	  ARG_NOCREATE=1; ;;
    x--prefix=*)
	extractFuncValue $1;
        ARG_PREFIX="$VALUE";
	;;
    x--gsmake=*)
	extractFuncValue $1;
        ARG_GSMAKE="$VALUE";
	;;
    x--configmake=*)
	extractFuncValue $1;
        ARG_CFGMAKE="$VALUE";
	;;
    "x--enable-debug")
        ARG_WITH_DEBUG=1
	;;
    "x--disable-debug")
        ARG_WITH_DEBUG=0
	;;
    "x--enable-strip")
        ARG_WITH_STRIP=1
	;;
    "x--disable-strip")
        ARG_WITH_STRIP=0
	;;
    x--with-ssl=*)
        extractFuncValue $1;
        ARG_CFGSSL="$VALUE"
	;;
    "x--enable-saml2")
        ARG_ENABLE_SAML2=1
	;;
    "x--enable-mfa")
        ARG_ENABLE_MFA=1
	;;
    "x--enable-sodium")
        ARG_ENABLE_SODIUM=1
	;;
    "x--disable-sodium")
        ARG_ENABLE_SODIUM=0
	;;
    "x--enable-ldap-config")
        ARG_WITH_LDAP_CONFIG=1
	;;
    "x--disable-ldap-config")
        ARG_WITH_LDAP_CONFIG=0
	;;

    *) echo "error: cannot process argument: $1"; exit 1; ;;
  esac
}

for i in $@; do
  processOption $i;
done

# load GNUstep environment
validateGNUstepArgs
# first we load the GNUstep.sh environment
. $DARG_GNUSTEP_SH
if test $ARG_BEQUIET != 1; then
  printGNUstepSetup;
fi

# ensure the parameters make sense
validateArgs

# start it
runIt
