#! /bin/sh

# Adapted from the ocamlnet configure script.

#######################################################################
# Helpers:

test_binary () {
  # $1: the name of the binary
  echo -n "Checking for $1 ... "
  if which "$1" >/dev/null 2>/dev/null; then
    echo "found"
    return 0
  else
    echo "not found"
    return 1
  fi
}

fail_binary () {
  echo
  echo "Required command '$1' not found!"
  [ -z "$2" ] || echo "===> $2"
  exit 1
}

check_binary () {
  # $1: the name of the binary
  # $2: an URL
  if test_binary "$1"; then
      return
  else
      fail_binary "$1" "$2"
  fi
}


test_library () {
  # $1: the name of the library (findlib)
  echo -n "Checking for $1 ... "
  if ocamlfind query $1 >/dev/null 2>/dev/null; then
    echo "found"
    return 0
  else
    echo "not found"
    return 1
  fi
}

fail_library () {
  echo
  echo "Required library $1 not found!"
  [ -z "$2" ] || echo "===> $2"
  exit 1
}

check_library () {
  # $1: the name of the library (findlib)
  # $2: an URL
  if test_library "$1"; then
      return
  else
      fail_library "$1" "$2"
  fi
}


#######################################################################
# Defaults

#--- Options ---
# value 0: off
# value 1: on
# defaults:

set_defaults () {
    name="eliom"
    enable_natdynlink=1
    enable_debug=0
    enable_annot=0
    with_preempt=1
    root=""
    temproot=""
    prefix="/usr/local"
    bindir=""
    mandir=""
    libdir=""
    docdir=""
    datadir=""
}

set_defaults
my_pwd=$(dirname $0)
version=$(head -n 1 $my_pwd/VERSION)
full_pwd=$(pwd)

########################################################################
## Option parsing
#
#
ehelp_debug="Enable/disable debug output"
ehelp_annot="Enable/disable .annot files"
ehelp_natdynlink="Enable/disable nativecode dynamic linking"

## Which options exist? eoptions for enable/disable, woptions for with/without:
eoptions="debug annot natdynlink"
woptions="preempt"

print_options () {
	for opt in $eoptions; do
		e="o=\$enable_$opt"
		eval "$e"
		uopt=$(echo $opt | sed -e 's/_/-/g')
		if [ $o -gt 0 ]; then
			echo "    --enable-$uopt"
		else
			echo "    --disable-$uopt"
		fi
	done
	for opt in $woptions; do
		e="o=\$with_$opt"
		eval "$e"
		uopt=$(echo $opt | sed -e 's/_/-/g')
		if [ $o -gt 0 ]; then
			echo "    --with-$uopt"
		else
			echo "    --without-$uopt"
		fi
	done
        case "$bindir" in
            "") bindir2="<prefix>/bin";;
            *) bindir2=$bindir;;
        esac

        case "$mandir" in
            "") mandir2="<prefix>/man";;
            *) mandir2=$mandir;;
        esac

        case "$libdir" in
            "") libdir2="\$(shell \${OCAMLFIND} printconf destdir)";;
            *) libdir2=$libdir;;
        esac

        case "$docdir" in
            "") docdir2="<prefix>/share/doc/\$(PROJECTNAME)";;
            *) docdir2=$docdir;;
        esac

        case "$datadir" in
            "") datadir2="<prefix>/share/\$(PROJECTNAME)";;
            *) datadir2=$datadir;;
        esac

	echo "    --name $name"
	echo "    --root $root"
	echo "    --temproot $temproot"
	echo "    --prefix $prefix"
	echo "    --bindir $bindir2"
	echo "    --mandir $mandir2"
	echo "    --libdir $libdir2"
	echo "    --docdir $docdir2"
	echo "    --datadir $datadir2"
}

usage () {
	set_defaults
	cat <<_EOF_ >&2
usage: ./configure [ options ]

  --enable-debug,	--disable-debug		Enable/disable debug output
  --enable-annot,	--disable-annot		Enable/disable .annot files generation
  --enable-natdynlink,	--disable-natdynlink	Enable/disable nativecode dynamic linking

  --with-preempt,	--without-preempt	compile with preemptive threads support.


  --name=NAME		The name of the library and ocamlfind package.

  --root=DIR		Root directory to install the package, every other options are relatives to this path. (usually /)
  --temproot=DIR	Temporary root directory to install the package (usually always "" but for package makers)
  --prefix=DIR		Subdirectory where to install binaries and libs (usually /usr or /usr/local)

  --bindir=DIR		Install binaries into this directory
  --mandir=DIR		Install manpages into this directory
  --libdir=DIR		Common directory for Ocsigen server's libraries
  --docdir=DIR		Install documentation in this directory
  --datadir=DIR		Install additional data files in this directory

Defaults are:

_EOF_
	print_options >&2
	exit 1
}


check_eopt () {
	for x in $eoptions; do
		if [ "$x" = "$1" ]; then
			return 0
		fi
	done
	echo "Unknown option: $1" >&2
	exit 1
}


check_wopt () {
	for x in $woptions; do
		if [ "$x" = "$1" ]; then
			return 0
		fi
	done
	echo "Unknown option: $1" >&2
	exit 1
}


echo "Welcome to Eliom version $version" >&2

while [ "$#" -gt 0 ]; do
	case "$1" in
		--enable-*)
			opt=$(echo "$1" | sed -e 's/--enable-//' -e 's/-/_/g')
			check_eopt "$opt"
			eval "enable_$opt=2"
			shift
			;;
		--disable-*)
			opt=$(echo "$1" | sed -e 's/--disable-//' -e 's/-/_/g')
			check_eopt "$opt"
			eval "enable_$opt=-1"
			shift
			;;
		--with-*)
			opt=$(echo "$1" | sed -e 's/--with-//' -e 's/-/_/g')
			check_wopt "$opt"
			eval "with_$opt=2"
			shift
			;;
		--without-*)
			opt=$(echo "$1" | sed -e 's/--without-//' -e 's/-/_/g')
			check_wopt "$opt"
			eval "with_$opt=-1"
			shift
			;;
		--root)
			root="$2"
			shift
			shift
			;;
		--temproot)
			temproot="$2"
			shift
			shift
			;;
		--prefix)
			prefix="$2"
			shift
			shift
			;;
		--name)
			name="$2"
			shift
			shift
			;;
                --bindir)
                        bindir="$2"
                        shift
                        shift
                        ;;
                --mandir)
                        mandir="$2"
                        shift
                        shift
                        ;;
                --libdir)
                        libdir="$2"
                        shift
                        shift
                        ;;
		--docdir)
			docdir="$2"
			shift
			shift
			;;
                --datadir)
                        datadir="$2"
                        shift
                        shift
                        ;;
		*)
                        echo "Unknown option: $1" >&2
			usage
	esac
done

case "$bindir" in
  "") bindir="$prefix/bin";;
esac

case "$mandir" in
  "") mandir="$prefix/man";;
esac

case "$libdir" in
  "") libdir="\$(shell \${OCAMLFIND} printconf destdir)";;
  *) libdir=$root$libdir
esac

case "$docdir" in
  "") docdir="$prefix/share/doc/\$(PROJECTNAME)";;
esac

case "$datadir" in
  "") datadir="$prefix/share/\$(PROJECTNAME)";;
esac


check_binary ocamlc "See: http://www.ocaml.org/"

check_ocamlversion () {

  echo -n "Checking for OCaml version... "
  version=$(ocamlc -version)
  echo $version
  n1=$(echo $version | sed 's/^\([0-9][0-9]*\)\..*$/\1/')
  n2=$(echo $version | sed 's/^[0-9][0-9]*\.\([0-9][0-9]*\)\..*$/\1/')
  # n3=`echo $version | sed 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)\..*$/\1/'`
  if [ $n1 -eq 3 ] && [ $n2 -lt 12 ]; then
      echo;
      echo "OCaml >= 3.12 is required. Aborting.";
      exit 1;
  fi

}

check_ocsigenserverversion () {

  echo -n "Checking for ocsigenserver version... "
  version=$(ocamlfind query ocsigenserver -l | grep version: | awk '{ print $2 }')
  echo $version
  n1=$(echo $version | sed 's/^\([0-9][0-9]*\)\..*$/\1/')
  n2=$(echo $version | sed 's/^[0-9][0-9]*\.\([0-9][0-9]*\).*$/\1/')
  # n3=`echo $version | sed 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)\..*$/\1/'`
  if [ $n1 -eq 1 ] && [ $n2 -lt 91 ]; then
      echo;
      echo "Ocsigenserver >= 1.91 is required. Aborting.";
      exit 1;
  fi

}

check_ocamlversion

check_binary ocamlfind "See: http://projects.camlcity.org/projects/findlib.html"

check_library ocsigenserver "See: http://ocsigen.org/ocsigenserver/"
check_ocsigenserverversion

check_library deriving-ocsigen "See: https://github.com/hnrgrgr/deriving"

check_binary js_of_ocaml "See: http://ocsigen.org/js_of_ocaml"
check_library js_of_ocaml.deriving "Missing support for deriving-ocsigen in js_of_ocaml"

check_library react "See: http://erratique.ch/software/react"

check_library lwt "See: http://ocsigen.org/lwt"
check_library lwt.unix  "Missing support for 'unix' in lwt."
check_library lwt.react "Missing support for 'react' in lwt."

check_library calendar "See: http://calendar.forge.ocamlcore.org/"
check_library cryptokit "See: http://pauillac.inria.fr/~xleroy/software.html#cryptokit"

######################################################################
# Summary

echo
echo "Effective options:"
print_options
echo

#Convert 0/1 values to YES/NO
if [ $enable_debug -gt 0 ] ; then
	enable_debug="YES"
else
	enable_debug="NO"
fi
if [ $enable_annot -gt 0 ] ; then
	enable_annot="YES"
else
	enable_annot="NO"
fi
if [ $enable_natdynlink -gt 0 ] ; then
	enable_natdynlink="YES"
else
	enable_natdynlink="NO"
fi
if [ $with_preempt -gt 0 ] ; then
	with_preempt="YES"
else
	with_preempt="NO"
fi

######################################################################
# Write Makefile.conf

echo "Writing Makefile.config"
cat <<_EOF_ > $my_pwd/Makefile.config

# The name of the library, ocamlfind package, etc.
PROJECTNAME := $name

#### External binaries ####

OCAMLFIND   := ocamlfind
OCAMLMKLIB  := ocamlmklib
JS_OF_OCAML := js_of_ocaml
CC          := gcc
INSTALL     := install




### Options ###

# Do you want preemptive threads ? YES/NO
PREEMPTIVE:=$with_preempt

# Do you want to use dynamic linking for native code? YES/NO
NATDYNLINK:=$enable_natdynlink

# Do you want debugging information (-g) ? YES/NO
DEBUG:=$enable_debug

# Do you want annot files (-dtypes) ? YES/NO
ANNOT:=$enable_annot

# Profiling (always put NO here - but if you want to debug eliom):
PROFILING:=NO



### Paths ###

# Temporary root directory to install the package (usually always "" but for package makers)
TEMPROOT = $temproot

# The directory for eliom compiler (binary):
BINDIR := $root$bindir

# Where to install Eliom tools manpages:
MANDIR := $root$mandir

# Where to install Eliom libraries:
LIBDIR := $libdir

# Where to put Eliom documentation:
DOCDIR := $root$docdir

# Where to install additional data:
DATADIR := $datadir

# The source directory (needed for local testing)
SRC := $full_pwd

include \$(SRC)/Makefile.options

_EOF_

######################################################################
# Finish

echo
echo
echo "Please check Makefile.config."
echo
echo "You can now compile Eliom by invoking:"
echo
echo "   make"
echo "   make doc"
echo
echo "You may want to test the extension before installation:"
echo
echo "   make run.local"
echo "   make run.opt.local"
echo
echo "Finally, if you want system-wide install, (become root if needed and) do"
echo
echo "   make install"
echo "   make install.doc"
echo
