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

AC_MODULE_INIT()

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])

if test "x$with_java" = xyes; then

  AC_MSG_CHECKING(which operating system we're 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're using)
  AC_CACHE_VAL(pike_cv_java_arch, [
    if test "x$pike_cv_java_sysos" = xwindows_nt; then
      uname=uname
    else
      uname=/usr/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`"; 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

  changequote({,})dnl
  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
      java_home_guess="`java -verbose 2>&1 | sed -e 's:^\[[^]/]*\(/.*\)/[^/]*\.jar[] ].*$:\1:' -e t -e d | sed -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/local/java*/jre /usr/local/jdk*/jre /usr/local/jre* "$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
      pike_cv_java_java_home="$JAVA_HOME"
    fi
  }})
  AC_MSG_RESULT($pike_cv_java_java_home)
  changequote([,])dnl

  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* "$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"
      ], [])

    else
      :
    fi
  else
    :
  fi

  if test "$pike_cv_java" = yes; then
    AC_MSG_CHECKING(if the JVM really works)
    AC_CACHE_VAL(pike_cv_java_working, [
      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>
#define JNI_CreateJavaVM createjavavm
typedef jint (JNICALL *createjavavmtype)(JavaVM **, void **, void *);
static createjavavmtype JNI_CreateJavaVM = NULL;
static HINSTANCE jvmdll = NULL;
#endif
        int main(int argc, char *argv[])
        {
          JavaVM *jvm;
          JNIEnv *env;
          JavaVMInitArgs vm_args;
          JavaVMOption vm_options[2];
	  jint res;
	  jmp_buf jbuf;
#ifdef __NT__
	  {
	    char *libname="jvm";
	    LPCSTR keyname=(LPCSTR)"SOFTWARE\\\\JavaSoft\\\\Java Runtime Environment\\\\1.2";
	    HKEY key;
	    char buffer[2*MAX_PATH+32];
	    DWORD type, len = sizeof(buffer)-1;
	
	    if(RegOpenKeyEx(HKEY_CURRENT_USER, keyname, 0,
			    KEY_READ, &key) == ERROR_SUCCESS ||
	       RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0,
			    KEY_READ, &key) == ERROR_SUCCESS) {
	      if(ERROR_SUCCESS == RegQueryValueEx(key, "RuntimeLib", 0, &type,
						  buffer, &len))
		switch(type) {
		case REG_SZ:
		  libname = buffer;
		  break;
		case REG_EXPAND_SZ:
		  type = ExpandEnvironmentStrings((LPCTSTR)buffer,
						  buffer+len,
						  sizeof(buffer)-len-1);
		  if(type && type<=sizeof(buffer)-len-1)
		    libname = buffer+len;
		  break;
		}
	      RegCloseKey(key);
	    }
	    if((jvmdll=LoadLibrary(libname))==NULL) {
              fprintf(stderr, "Can't load library %s\\n", libname);
              exit(1);
	    } else {
	      FARPROC proc;
	      if(proc=GetProcAddress(jvmdll, "JNI_CreateJavaVM"))
		JNI_CreateJavaVM = (createjavavmtype)proc;
	      else {
		if(FreeLibrary(jvmdll))
		  jvmdll = NULL;
	        fprintf(stderr, "Can't GetProcAddress %s\\n", "JNI_CreateJavaVM");
                exit(1);
	      }
	    }
	  }
#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);
	  return 0;
        };
      ], [pike_cv_java_working=yes], [pike_cv_java_working=no])
    ])
    AC_MSG_RESULT($pike_cv_java_working)
    if test "$pike_cv_java_working" = no; then
      pike_cv_java=no;
    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
      dnl We'll do LoadLibrary ourselves instead of relying on jvm.lib to
      dnl 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) pike_cv_java_cpu=ppc;;
      *) 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);;
  esac

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

  true
else
  :
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 )
