#!/bin/sh -e

#####################################################
# this configure-script searches for the needed includes
# and libraries.
#
# it is MUCH faster, smaller and does what I want. :-)
#
# If you have openssl installed in
# an unusual directory like /home/me/install/ssl
# just give it as argument to ./configure
# it then searches for headers in /home/me/install/ssl/include
# and librarys in /home/me/install/ssl/lib
#
# if you have a very unusual setup or you are cross-compiling
# you can edit "Local.mak" to fit your needs and to reflect your setup
#
# The Makefiles should support parallel builds.
#
#######################################################

TOPDIR="`cd $(dirname $0) && pwd`"
read VERSION < ${TOPDIR}/VERSION

cat <<EOF >reconfigure
export QTDIR="$QTDIR"
export CFLAGS="${CFLAGS}"
export LDFLAGS="${LDFLAGS}"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
export prefix="${prefix}"
export docdir="${docdir}"
export RC="stop"
exec $0 $@
EOF
chmod 755 reconfigure

cat <<EOF


      Configuring XCA ${VERSION}
---------------------------------------------

EOF

DIRS=""

for dir in $@; do
  DIRS="$DIRS `cd $dir; pwd`"
done

DIRS="$QTDIR $DIRS /usr /usr/X11R6 /usr/local"
STDINC="-I/usr/include"
STDLIB="-L/usr/lib"
prefix=${prefix:=/usr/local}
CFLAGS=${CFLAGS:=-Wall -ggdb -O2}
CC=${CC:=gcc}
LDFLAGS=""
LIBS="-lstdc++"
LDIRS=
MOC=moc
UIC=uic
LRELEASE=lrelease

test -z "$docdir" && docdir="${prefix}/share/xca"

DVERSION="`gcc --version | grep apple-darwin || :`"
case "$DVERSION" in
  *-apple-darwin11*) DARWIN="Lion" ;;
  *-apple-darwin10*) DARWIN="SnowLeopard" ;;
  *-apple-darwin9*) DARWIN="Leopard" ;;
  *-apple-darwin*)
    echo Unsupported Mac OS version $DVERSION
    exit 1
    ;;
esac

if test -n "$DARWIN"; then
  echo Configuring for Mac OSX $DARWIN
  LDFLAGS="${LDFLAGS} -framework QtCore -framework QtGui -arch i386"
  CFLAGS="${CFLAGS} -pipe -gdwarf-2 -arch i386"
  LIBS="${LIBS} -lltdl"
  if test -d "$QTDIR"; then
    CF="-F$QTDIR/lib $CF"
    CFLAGS="-F$QTDIR/lib $CFLAGS"
    MACDEPLOYQT=$QTDIR/bin/macdeployqt
    TRANSLATIONS=$QTDIR/translations
  else
    for mdq in macdeployqt macdeployqt-4.6; do
      if which ${mdq}; then
        MACDEPLOYQT=${mdq}
        break
      fi
    done
    TRANSLATIONS=/Developer/Applications/Qt/translations
  fi
fi

if test -x /sbin/ldconfig; then
  EXTRALIB=$(
  /sbin/ldconfig -p | sed 's,.* => \(/.*/\)[^/]*\.so.*,\1,' | grep "^/" | sort -u | \
  while read lib; do
    echo -n "-L${lib} "
  done
  echo "$DIR"
  )
  STDLIB="$STDLIB $EXTRALIB"
fi

err() {
  echo
  echo ERROR: $1
  echo
  err_occ=Y
}

#adds an includedir to $CF
add_include() {
  for _dir in $STDINC ${CF}; do
    if test "-I$1" = "${_dir}"; then
      return 0
    fi
  done

  CF="${CF} -I$1"
}

add_lib() {
  if test "$3" = "a"; then
    SLIBS="$SLIBS -l$2"
  else
    LIBS="$LIBS -l$2"
  fi
  for _libs in ${STDLIB} ${LDIRS}; do
    if test "-L$1" = "${_libs}"; then
      return 0
    fi
  done

  LDIRS="${LDIRS} -L$1"
}

# check for includes
search_includes() {
  for dir in ${DIRS};  do
    for dbn in "" ${subdirs}; do
      for include in outinc include; do
        if test -r "${dir}/${include}${dbn}/$1"; then
          add_include ${dir}/${include}${dbn}
	  test -z "${dbn}" || add_include ${dir}/${include}
          echo "Found: $1 at ${dir}/${include}${dbn}"
          return 0
        fi
      done
    done
  done
  return 1
}

# check for libs
search_lib() {
  for dir in ${DIRS};  do
    for dbn in $@; do
      for suffix in so dylib obj a; do
        for lib in lib lib64 lib32 out; do
          if test -r "${dir}/${lib}/lib${dbn}.${suffix}"; then
            add_lib "${dir}/${lib}" "${dbn}" "${suffix}"
	    echo "Found: lib${dbn}.${suffix} at ${dir}/${lib}"
            return 0
	  fi
	done
      done
    done
  done
  return 1
}

check_frameworks() {
  for fw in $@; do
    for dir in $QTDIR/lib /Library/Frameworks; do
      if test -d $dir/${fw}.framework; then
        return 0
      fi
    done
  done
  return 1
}

if test "$#" = "0" && test -z "$DARWIN" && test -z "$QTDIR" && \
   pkg-config QtGui openssl --libs >/dev/null;
then
  CF="`pkg-config QtGui openssl --cflags`"
  LIBS="`pkg-config QtGui openssl --libs` -lltdl"
else
  by_hand=true
fi

if test "$by_hand" = "true"; then
  ######################### QT
  if test -z "$DARWIN"; then
    subdirs="/qt /qt4"
    search_includes QtCore/QObject || err "The QT Library headerfiles were not found. Set QTDIR appropriately."
    search_lib QtCore4 QtCore || err "The QT Core library was not found."
    search_lib QtGui4 QtGui || err "The QT Gui library was not found."
    search_lib ltdl || err "Libtool ltdl not found."
    search_lib c_r || true
  else
    check_frameworks QtGui QtCore || err "QT Framework not found, needed on Mac OSX, please install QT"
  fi

  ###################### OpenSSL
  subdirs=""
  search_includes openssl/opensslv.h || err "The OpenSSL library headerfiles were not found."
  search_lib crypto || err "The OpenSSL library was not found."
fi

cat << EOF

CFLAGS=${CFLAGS}
CPPFLAGS=${CF}
LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
PREFIX=${prefix}
docdir=${docdir}

EOF

export LD_LIBRARY_PATH

##### Try to compile them all together and show the versions.
cat >conftest.cpp <<EOF
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#include <QtCore/qglobal.h>
#define WARN "###################### WARNING ######################"
int main(){
  char buf[2048] = "";
  printf("\nThe Versions of the used libraries are:\n"
	"Header:\n"
	"\t%s 0x%lxL\n"
	"\tQT: %s\n"
	"Libraries:\n"
	"\t%s\n"
	"\tQT: %s\n",
		OPENSSL_VERSION_TEXT, OPENSSL_VERSION_NUMBER,
		QT_VERSION_STR,
		SSLeay_version(SSLEAY_VERSION),
		qVersion()
	);

  if (QT_VERSION < 0x040300) {
	printf("You need Qt 4.3.0 or higher\n");
	return 1;
  }
  if ( OPENSSL_VERSION_NUMBER < 0x00908000L ) {
	printf("You need OpenSSL >= 0.9.8 or higher\n");
	return 1;
  }
  if (strcmp(QT_VERSION_STR, qVersion()))
	strcat(buf, "The versions of the QT headers and library differ\n");
  if (strcmp(OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)))
	strcat(buf, "The versions of the OpenSSL headers and library differ\n");
#ifdef OPENSSL_NO_EC
  strcat(buf, "This OpenSSL installation has no EC cryptography support\n");
#endif
  if (buf[0])
	printf("\n\n" WARN "\n%s" WARN "\n\n", buf);
  return 0;
}
EOF

echo "${CC} $LDIRS $LIBS $CF $CFLAGS ${LDFLAGS} conftest.cpp -o conftest${SUFFIX}" >conftest.log
if ${CC} $LIBS $LDIRS $CF $CFLAGS ${LDFLAGS} conftest.cpp -o conftest${SUFFIX} >> conftest.log 2>&1; then
  if ! ./conftest${SUFFIX}; then
    err "Unable to execute a freshly compiled application, maybe you have to adjust your LD_LIBRARY_PATH or /etc/ld.so.conf"
  else
    rm -rf conftest.cpp conftest${SUFFIX} conftest.log conftest.dSYM
  fi
else
  err "Unable to compile a minimal application look at 'conftest.log' for errors"
fi


if which linuxdoc 2>&1; then
  LINUXDOC="linuxdoc"
else
  echo "Application 'linuxdoc' not found."
  if tar ztf ${TOPDIR}/doc/xca-doc.tgz xca.html >/dev/null 2>&1; then
    echo "But Found a valid documentation package 'doc/xca-doc.tgz'"
  else
   echo "No documentation will be generated."
  fi
  LINUXDOC=":"
fi

findapp() {
  for app in `which $@ 2>/dev/null`; do
    if test -x "$app"; then
      echo "$app"
      break
    fi
  done
}
if test -z "$QTDIR"; then
  MOC=`findapp moc4 moc-qt4 moc`
  UIC=`findapp uic4 uic-qt4 uic`
  RCC=`findapp rcc4 rcc-qt4 rcc`
  LRELEASE=`findapp lrelease4 lrelease-qt4 lrelease`
else
  MOC=$QTDIR/bin/moc
  UIC=$QTDIR/bin/uic
  RCC=$QTDIR/bin/rcc
  LRELEASE=$QTDIR/bin/lrelease
fi
cat >Local.mak <<EOF
export TOPDIR=${TOPDIR}
export VERSION=${VERSION}
CPPFLAGS=$CF
CFLAGS=${CFLAGS} $LDIRS

LDFLAGS=$LDFLAGS

# List of all libs to be compiled statically
SLIBS=$SLIBS

# list of dynamic libraries
LIBS=$LIBS

MOC=$MOC
UIC=$UIC
RCC=$RCC
LRELEASE=$LRELEASE
MACDEPLOYQT=$MACDEPLOYQT
QMAKE=qmake
DARWIN=$DARWIN
TRANSLATIONS=$TRANSLATIONS

CC=${CC}
LD=${LD:=ld}
STRIP=${STRIP:=strip}
WINDRES=${WINDRES:=windres}
MAKENSIS=${MAKENSIS:=makensis.exe}
LINUXDOC=${LINUXDOC:=linuxdoc}

SUFFIX=${SUFFIX}
HOST=linux
prefix=${prefix}
docdir=${docdir}

EOF
test -z "$etc" && etc=/etc/xca

cat >local.h <<EOF
#define PREFIX "$prefix"
#define ETC "$etc"
#define VER "${VERSION}"
#define DOCDIR "$docdir"
EOF

find_make() {
  for dirs in /usr/local/bin /sw/bin /bin /usr/bin; do
    for make in make gmake; do
      if "${dirs}/${make}" -v 2>/dev/null | grep GNU; then
	mak="${dirs}/${make}"
	return
      fi
    done
  done
}

find_make

echo
if test ! -z "${mak}"; then
  echo "A usable 'make' executable was found in ${mak}"
else
  echo "No usable 'make' executable found."
fi
echo

if test "x${err_occ}" = "xY"; then
  echo
  echo "An error occured. Please edit 'Local.mak' manually if compiling fails."
fi

test -f Makefile || ln -s ${TOPDIR}/Makefile
