AC_INIT(jvm.c)
AC_CONFIG_HEADER(config.h)

AC_MODULE_INIT()

MODULE_PMOD_IN=module.pmod.in

OLD_LIBS=$LIBS
OLD_LDFLAGS=$LDFLAGS
OLD_CPPFLAGS=$CPPFLAGS
OLD_LIBPATH=$LIBPATH
JAVA_LIBS=""
JAVA_LIBPATH=""
JAVA_AVAILABLE=0
LINKER_OPTIONS=""

AC_ARG_WITH(java,  [  --without-java       no support for Java],[],[with_java=yes])
AC_ARG_WITH(java-include-dir, 
	[  --with-java-include-dir=dir    look for header-files in dir],
	[pike_java_user_include_directory=$withval])
AC_ARG_WITH(java-lib-dir, 
	[  --with-java-lib-dir=dir    look for JRE libs in dir],
	[pike_java_user_lib_directory=$withval])

PIKE_FEATURE_WITHOUT(Java)

if test "x$with_java" = xyes; then

  PIKE_FEATURE_NODEP(Java)

  AC_MSG_CHECKING(which operating system we are using)
  AC_CACHE_VAL(pike_cv_java_sysos, [
    pike_cv_java_sysos="`uname | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`"
    case "$pike_cv_java_sysos" in
      sunos)
        case "`uname -r`" in
          5.*|6.*|7.*) pike_cv_java_sysos="solaris";
        esac
      ;;
    esac
  ])
  AC_MSG_RESULT($pike_cv_java_sysos)

  AC_MSG_CHECKING(which architecture we are using)
  AC_CACHE_VAL(pike_cv_java_arch, [
    if test "x$pike_cv_java_sysos" = xwindows_nt; then
      uname=uname
    elif test -f "/usr/bin/uname"; then
      uname=/usr/bin/uname
    else
      uname=/bin/uname
    fi
    if test aix = "$pike_cv_java_sysos" && aix_cputype=`/usr/sbin/lsattr -El proc0 | awk '$1=="type" { print $2; ok=1; exit } END { exit !ok }'`; then
      case "$aix_cputype" in
	PowerPC*) pike_cv_java_arch=powerpc;;
	POWER*) pike_cv_java_arch=rs6000;;
	*) pike_cv_java_arch="`echo $aix_cputype | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`";;
      esac
    else
      if pike_cv_java_arch="`$uname -p || uname -p 2>/dev/null`"; then :;
      else pike_cv_java_arch=no; fi
    fi

    dnl Linux kluge

    if test x"$pike_cv_java_arch" = xunknown; then
      [pike_cv_java_arch="`uname -m | sed -e 's/^i[4-9]86/i386/'`"]
    fi
  ])
  AC_MSG_RESULT($pike_cv_java_arch)

  AC_MSG_CHECKING(what kind of threads to use)
  AC_CACHE_VAL(pike_cv_java_threads_type, [
    if test "x$THREADS_FLAG" = x; then
      pike_cv_java_threads_type=native_threads
    else
      pike_cv_java_threads_type="${THREADS_FLAG}_threads"
    fi
  ])
  AC_MSG_RESULT($pike_cv_java_threads_type)

  if test x"$pike_cv_java_threads_type" = xnative_threads; then
    :
  else
    AC_MSG_WARN([Only native_threads are known to work.])
    AC_MSG_WARN([If you are unsure, please unset \$THREADS_FLAG and rerun configure.])
  fi

  AC_MSG_CHECKING(for working ls)
  AC_CACHE_VAL(pike_cv_ls, [
    pike_cv_ls=no
    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
    for ac_dir in $PATH; do
      if test -x "$ac_dir"/ls && "$ac_dir"/ls . >/dev/null 2>&1; then
        if "$ac_dir"/ls ./fnord/fnord/fnord/fnurkelfoo 2>/dev/null; then
	  :
	else
	  pike_cv_ls="$ac_dir"/ls
	fi
      else
	:
      fi
    done
    IFS="$ac_save_ifs"
  ])
  AC_MSG_RESULT($pike_cv_ls)
  if test no = "$pike_cv_ls"; then
    AC_MSG_WARN([no working ls found!  Java configure will almost certainly fail.])
    LS="false"
  else
    LS="$pike_cv_ls"
  fi

  AC_MSG_CHECKING(for JAVA_HOME)

  AC_CACHE_VAL(pike_cv_java_java_home, [[
    if test "x$JAVA_HOME" = x; then
      pike_cv_java_java_home=no

      # balance brackets: [ 
      #
      # I know this is bloody ugly, bug in modern (>2.13) 
      # autoconf's changequote doesn't work (and this is 
      # the only thing that breaks so far) /Mirar

      java_home_guess="`java -verbose fnord.fnord.fnord 2>&1 | sed -e 's:^\[[^]/]*\(/.*\)/[^/]*\.\(jar\|zip\)[] ].*$:\1:' -e t -e d | sed -e 's:^.* from /:/:' -e 's:/[Cc]lasses$::' -e 's:/lib$::' -e 1q`"
      for tmp_java_home in /usr/java /usr/local/java /usr/local/jdk* /usr/java*/jre /usr/java/jdk*/jre /usr/local/java*/jre /usr/local/jdk*/jre /usr/local/jre* /usr/local/j2sdk*/jre /usr/local/j2re* "$java_home_guess" "$pike_java_user_lib_directory"/..; do
        if test -d $tmp_java_home/.; then
          if "$LS" "$tmp_java_home/lib/$pike_cv_java_arch/$pike_cv_java_threads_type"/libjvm* >/dev/null 2>&1 || \
	    "$LS" "$tmp_java_home/lib/$pike_cv_java_arch"/libjvm* >/dev/null 2>&1 || \
	    "$LS" "$tmp_java_home/lib/$pike_cv_java_arch"/classic/libjvm* >/dev/null 2>&1 || \
	    "$LS" "$tmp_java_home/bin"/classic/libjvm* >/dev/null 2>&1 || \
	    "$LS" "$tmp_java_home/Libraries"/libjvm* >/dev/null 2>&1; then
	      pike_cv_java_java_home="$tmp_java_home"
	  else
	    :
	  fi
        else
          :
        fi
      done
    else
      if test -d "$JAVA_HOME"/jre/lib; then
        pike_cv_java_java_home="$JAVA_HOME"/jre
      else
        pike_cv_java_java_home="$JAVA_HOME"
      fi
    fi
  ]])
  AC_MSG_RESULT($pike_cv_java_java_home)

  AC_MSG_CHECKING(for Java libraries)
  AC_CACHE_VAL(pike_cv_java_lib_dir, [
    pike_cv_java_lib_dir=""
    if test -z "$pike_java_user_lib_directory"; then
      tmp_java_lib_dir="$pike_cv_java_java_home/lib"
    else
      tmp_java_lib_dir="$pike_java_user_lib_directory"
    fi
    for i in "$pike_cv_java_arch/$pike_cv_java_threads_type" \
             "$pike_cv_java_arch/classic" "$pike_cv_java_arch" \
	     "." "../bin" "../bin/classic"; do
      if test -d "$tmp_java_lib_dir/$i/." && "$LS" $tmp_java_lib_dir/$i/lib* >/dev/null 2>&1; then
        pike_cv_java_lib_dir="$pike_cv_java_lib_dir$tmp_java_lib_dir/$i "
      else
	:
      fi
    done
    if test -z "$pike_cv_java_lib_dir" ; then pike_cv_java_lib_dir=no; else
      :
    fi
  ])
  AC_MSG_RESULT($pike_cv_java_lib_dir)

  if test "x$pike_cv_java_lib_dir" = xno; then :; else
    echo Adding $pike_cv_java_lib_dir to the library search path.
    for i in $pike_cv_java_lib_dir; do
      LDFLAGS="-L$i -R$i ${LDFLAGS}"
      LINKER_OPTIONS="-L$i -R$i ${LINKER_OPTIONS}"
      JAVA_LIBPATH="${JAVA_LIBPATH}${JAVA_LIBPATH:+:}$i"
      LIBPATH="${LIBPATH}${LIBPATH:+:}$i"
    done
    export LIBPATH
  fi

  AC_MSG_CHECKING(for the Java include directory)
  AC_CACHE_VAL(pike_cv_java_include_dir, [
    pike_cv_java_include_dir=no
    for tmp_java_incdir in /usr/java* /usr/local/java* /usr/local/jdk* /usr/local/jre* /usr/local/j2sdk* "$pike_cv_java_java_home"/../.. "$pike_cv_java_java_home"/.. "$pike_cv_java_java_home" "$pike_java_user_include_directory"; do
      if test -d $tmp_java_incdir/. && "$LS" "$tmp_java_incdir/include/jni.h" >/dev/null 2>&1 ; then
	 pike_cv_java_include_dir="$tmp_java_incdir/include"
      else
        if test -d $tmp_java_incdir/. -a -d $tmp_java_incdir/Headers/. &&\
        	  "$LS" "$tmp_java_incdir/Headers/jni.h" >/dev/null 2>&1 ; then
	  pike_cv_java_include_dir="$tmp_java_incdir/Headers"
	else
	  :
	fi
      fi
    done
  ])
  AC_MSG_RESULT($pike_cv_java_include_dir)

  if test "x$pike_cv_java_include_dir" = xno; then :; else
    echo "Adding $pike_cv_java_include_dir to the include search path."
    CPPFLAGS="-I$pike_cv_java_include_dir ${CPPFLAGS}"
    if test -d "$pike_cv_java_include_dir/$pike_cv_java_sysos/."; then
      echo "Adding $pike_cv_java_include_dir/$pike_cv_java_sysos to the include search path."
      CPPFLAGS="-I$pike_cv_java_include_dir/$pike_cv_java_sysos ${CPPFLAGS}"
    else
      :
    fi
    if test -d "$pike_cv_java_include_dir/$pike_cv_java_arch/."; then
      echo "Adding $pike_cv_java_include_dir/$pike_cv_java_arch to the include search path."
      CPPFLAGS="-I$pike_cv_java_include_dir/$pike_cv_java_arch ${CPPFLAGS}"
    else
      :
    fi
  fi

  AC_MSG_CHECKING([for JavaVM (MacOS X)])
  AC_CACHE_VAL(pike_cv_java_javavm, [
    pike_cv_java_javavm=no;
    for tmp_java_javavm in ../.. .. .; do
      if test -f "$pike_cv_java_java_home"/"$tmp_java_javavm"/JavaVM; then
        pike_cv_java_javavm="$pike_cv_java_java_home"/"$tmp_java_javavm"/JavaVM
      else
        :
      fi
    done
  ])
  AC_MSG_RESULT($pike_cv_java_javavm)

  if test osf1 = "$pike_cv_java_sysos"; then
    CPPFLAGS="-D_REENTRANT $CPPFLAGS"
  else
    :
  fi
  AC_CHECK_HEADERS(jni.h winbase.h setjmp.h)

  pike_cv_java=no

  if test "$ac_cv_header_jni_h" = yes; then

    AC_CHECK_LIB(hpi, sysOpen, [
      LIBS="$LIBS -lhpi"
      JAVA_LIBS="${JAVA_LIBS} -lhpi"
    ], [])

    if test x"$pike_cv_java_javavm" = xno; then
      :
    else
      AC_MSG_CHECKING([for JNI_CreateJavaVM in "$pike_cv_java_javavm"])
      AC_CACHE_VAL(ac_cv_lib_javavm_JNI_CreateJavaVM, [
        ac_save_LIBS="$LIBS"
        LIBS="$pike_cv_java_javavm $LIBS"
        AC_TRY_LINK([#include <jni.h>], dnl
	  [JNI_CreateJavaVM((JavaVM**)0,(void**)0,(void*)0);], dnl
	  [ac_cv_lib_javavm_JNI_CreateJavaVM=yes], dnl
	  [ac_cv_lib_javavm_JNI_CreateJavaVM=no])
        LIBS="$ac_save_LIBS"
      ])
      if test x"$ac_cv_lib_javavm_JNI_CreateJavaVM" = xyes; then
        LIBS="$pike_cv_java_javavm $LIBS"
        JAVA_LIBS="$pike_cv_java_javavm ${JAVA_LIBS}"
        pike_cv_java=yes;
        AC_MSG_RESULT(yes)
      else
        AC_MSG_RESULT(no)
      fi      
    fi

    if test x"$pike_cv_java" = xyes; then
      :
    else

      AC_MSG_CHECKING([for JNI_CreateJavaVM in -ljvm])
      AC_CACHE_VAL(ac_cv_lib_jvm_JNI_CreateJavaVM, [
        ac_save_LIBS="$LIBS"
        LIBS="-ljvm $LIBS"
        AC_TRY_LINK([#include <jni.h>], dnl
	  [JNI_CreateJavaVM((JavaVM**)0,(void**)0,(void*)0);], dnl
	  [ac_cv_lib_jvm_JNI_CreateJavaVM=yes], dnl
	  [ac_cv_lib_jvm_JNI_CreateJavaVM=no])
        LIBS="$ac_save_LIBS"
      ])
      if test x"$ac_cv_lib_jvm_JNI_CreateJavaVM" = xyes; then
        LIBS="-ljvm $LIBS"
        JAVA_LIBS="-ljvm ${JAVA_LIBS}"
        pike_cv_java=yes;
        AC_MSG_RESULT(yes)
      else
        AC_MSG_RESULT(no)
      fi

    fi

    if test "$pike_cv_java" = yes; then

      AC_CHECK_LIB(java, Java_java_lang_Class_isInstance, [
        LIBS="-ljava $LIBS"
        JAVA_LIBS="-ljava ${JAVA_LIBS}"
      ], [])

      AC_CHECK_LIB(zip, Java_java_util_zip_Inflater_inflateBytes, [
        LIBS="-lzip $LIBS"
        JAVA_LIBS="-lzip ${JAVA_LIBS}"
      ], [])

      AC_CHECK_LIB(thread, thr_create, [
        LIBS="$LIBS -lthread"
        JAVA_LIBS="${JAVA_LIBS} -lthread"
	LINKER_OPTIONS="${LINKER_OPTIONS} -lthread"
      ], [])

      # Java/AIX has this. For debug...
      AC_CHECK_LIB(java, ibmFindDLL, [
        AC_DEFINE(HAVE_IBMFINDDLL)
      ])
    else
      :
    fi
  else
    :
  fi

  PIKE_FEATURE(Java,[no (no known JVM found)])

  if test "$pike_cv_java" = yes; then
    AC_MSG_CHECKING(if the JVM really works)
    AC_CACHE_VAL(pike_cv_java_working, [
      OLD_CPPFLAGS="$CPPFLAGS"
      CPPFLAGS="-I$srcdir $OLD_CPPFLAGS"
      AC_TRY_RUN([#ifdef HAVE_JNI_H
#include <jni.h>
#endif
#ifdef HAVE_SETJMP_H
#include <setjmp.h>
#endif
#include <stdio.h>
#ifdef __NT__
#include <windows.h>
#include "ntdl.c"
#endif
        int main(int argc, char *argv[])
        {
          JavaVM *jvm;
          JNIEnv *env;
          JavaVMInitArgs vm_args;
          JavaVMOption vm_options[2];
	  jint res;
	  jmp_buf jbuf;
#ifndef __NT__
	  alarm(50);
#endif
#ifdef __NT__
	  switch(open_nt_dll()) {
	    case -1:
	      fprintf(stderr, "Can't load DLL\\n");
              exit(1);
	    case -2:
              fprintf(stderr, "Can't GetProcAddress %s\\n", "JNI_CreateJavaVM");
	    default:
              exit(1);
	    case 0:
	      ;
	  }
#endif
          vm_args.version = 0x00010002;
          vm_args.nOptions = 0;
          vm_args.options = vm_options;
          vm_args.ignoreUnrecognized = JNI_TRUE;
#ifndef __NT__
          vm_options[0].optionString = "-Djava.library.path=$JAVA_LIBPATH";
          vm_options[0].extraInfo = NULL;
          vm_args.nOptions++;
#endif
          if((res=JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args))) {
	    fprintf(stderr, "JNI_CreateJavaVM failed code %d\\n", (int)res);
            exit(1);
	  }
	  if(!setjmp(jbuf))
	    longjmp(jbuf,1);
#ifdef HAVE_IBMFINDDLL
	  {
	    /* Debug... */
	    extern char *ibmFindDLL(void);
	    fprintf(stderr, "ibmFindDLL: \"%s\"\n", ibmFindDLL());
	  }
#endif
	  return 0;
        };
      ], [pike_cv_java_working=yes], [pike_cv_java_working=no])
      CPPFLAGS="$OLD_CPPFLAGS"
    ])
    AC_MSG_RESULT($pike_cv_java_working)
    PIKE_FEATURE(Java,[yes ($JAVA_LIBS)])
    if test "$pike_cv_java_working" = no; then
      pike_cv_java=no;
      PIKE_FEATURE(Java,[no (JVM does not work)])
    fi
  else
    :
  fi

  if test "x$pike_cv_java" = xno; then
    LIBS="$OLD_LIBS"
    CPPFLAGS="$OLD_CPPFLAGS"
    LDFLAGS="$OLD_LDFLAGS"
    JAVA_LIBS=""
    LINKER_OPTIONS=""
  else
    AC_DEFINE(HAVE_JAVA)
    JAVA_AVAILABLE=1
    if test "x$pike_cv_java_java_home" = xno; then :; else
      AC_DEFINE_UNQUOTED(JAVA_HOME, "${pike_cv_java_java_home}")
    fi
    if test "x$pike_cv_sys_os" = xWindows_NT ; then
      # We'll do LoadLibrary ourselves instead of relying on jvm.lib to
      # do it for us.  That way we'll avoid nasty popup dialogs...
      JAVA_LIBS=""
    else
      :
    fi
  fi

  AC_MSG_CHECKING(for known machine language)
  AC_CACHE_VAL(pike_cv_java_cpu, [
    case $pike_cv_java_arch  in
      sparc) pike_cv_java_cpu=sparc;;
      i386|x86) pike_cv_java_cpu=x86;;
      powerpc|ppc) pike_cv_java_cpu=ppc;;
      alpha) pike_cv_java_cpu=alpha;;
      *) pike_cv_java_cpu=no;;
    esac
  ])
  AC_MSG_RESULT($pike_cv_java_cpu)

  case $pike_cv_java_cpu in
    sparc) AC_DEFINE(HAVE_SPARC_CPU);;
    x86) AC_DEFINE(HAVE_X86_CPU);;
    ppc) AC_DEFINE(HAVE_PPC_CPU);;
    alpha) AC_DEFINE(HAVE_ALPHA_CPU);;
  esac

  if test "x$JAVA_LIBPATH" = x; then :; else
    AC_DEFINE_UNQUOTED(JAVA_LIBPATH, "${JAVA_LIBPATH}")
  fi

  true
else
  :
fi

if test x"${pike_cv_java}${pike_cv_sys_os}" = xyesWindows_NT ; then
  JAVA_LIBS="-lkernel32 -lws2_32 -ladvapi32 $JAVA_LIBS"
  PIKE_FEATURE(Java,[yes ($JAVA_LIBS)])
fi


LIBPATH="$OLD_LIBPATH"

AC_SUBST(LINKER_OPTIONS)
AC_SUBST(JAVA_LIBS)
AC_SUBST(JAVA_AVAILABLE)

AC_OUTPUT(Makefile module.pmod.in,echo FOO >stamp-h )
