#!/bin/bash
# packaging script for TuttleOFX on OSX
# author: Frederic Devernay

if [ ! -d bin -o ! -f bin/sam-do ]; then
  echo "Error: bin/sam-do does not exist"
  echo "This script must be run in the TuttleOFX install directory."
  echo "To compile, execute the following commands, starting from the TuutleOFX"
  echo "source tree:"
  echo "mkdir build"
  echo "cd build"
  echo "export LIBRARY_PATH=/opt/local"
  echo 'cmake -DCMAKE_PREFIX_PATH="/opt/local;/opt/libjpeg-turbo" -DPYTHON_INCLUDE_DIR=/opt/local/Library/Frameworks/Python.framework/Headers -DOPENIMAGEIO_INCLUDE_DIR=/opt/local/include/OpenImageIO -DCMAKE_INSTALL_PREFIX=/opt/TuttleOFX -DCMAKE_OSX_ARCHITECTURES="i386;x86_64" ..'
  echo "make -j4"
  echo "make install"
  exit 1
fi

PACKAGE="TuttleOFX"
ROOT="/tmp/$PACKAGE-root-$$"
OFX="/Library/OFX"
MACPORTS=/opt/local
changes=""
#PKGEXT=-plugins
PKGEXT=

# env LANG=C is necessary so that sed doesn't try to interpret the binary file with a specific encoding
LANG=C
export LANG

#APPSUPPORT="/Library/Application Support/$PACKAGE"
APPSUPPORT="/opt/$PACKAGE"
APPLIB="$APPSUPPORT/lib"
APPBIN="$APPSUPPORT/bin"
APPOFX="$APPSUPPORT/OFX"
FRAMEWORKS="$APPSUPPORT/Library/Frameworks"
PYTHONDIR=`python -m site |grep "'/Library/Python" | sed -e "s/^ *'//" -e "s/', *//"`

echo "Info: copying..."
rm -rf ${ROOT}
mkdir ${ROOT}
mkdir -p "${ROOT}$APPLIB"  "${ROOT}$FRAMEWORKS" "${ROOT}$APPOFX"  "${ROOT}$APPSUPPORT/share"

ditto bin "${ROOT}$APPBIN"
ditto lib "${ROOT}$APPLIB"
ditto OFX "${ROOT}$APPOFX"
mkdir -p "${ROOT}$OFX/Plugins"
ln -s "$APPOFX" "${ROOT}$OFX/Plugins/$PACKAGE"

#ditto python "${ROOT}$PYTHONDIR"

LIBADD=

# Check that ImageMagick is properly installed
if ! pkg-config --modversion ImageMagick >/dev/null 2>&1; then
    echo "Missing ImageMagick -- please install ImageMagick using MacPorts (without X11 support) and try again: 'sudo port install ImageMagick +no_x11'" >&2
    exit 1
fi

# Update the ImageMagick path in startup script.
IMAGEMAGICKVER=`pkg-config --modversion ImageMagick`
IMAGEMAGICKMAJ=${IMAGEMAGICKVER%.*.*}

# copy the ImageMagick libraries (.la and .so)
cp -r "$MACPORTS/lib/ImageMagick-$IMAGEMAGICKVER" "${ROOT}$APPLIB"
cp -r "$MACPORTS/share/ImageMagick-$IMAGEMAGICKMAJ" "${ROOT}$APPSUPPORT/share"

LIBADD="$LIBADD ${ROOT}$APPLIB/ImageMagick-$IMAGEMAGICKVER/modules-*/*/*.so"

# copy the turbojpeg library
l=/opt/libjpeg-turbo/lib/libturbojpeg.[0-9].dylib
cp $l "${ROOT}$APPLIB"
changes="$changes -change `echo $l` $APPLIB/`basename $l`"

#copy the CTL libraries
#(they now have their own port)
#for i in IlmCtlSimd IlmCtl) IlmCtlMath; do
#    l=../../../../3rdparty/ctl/${i}/.libs/lib${i}.[0-9].dylib
#    cp $l "${ROOT}$APPLIB"
#    changes="$changes -change $MACPORTS/lib/`basename $l` $APPLIB/`basename $l` -change /usr/local/lib/`basename $l` $APPLIB/`basename $l`"
#done

echo "Info: looking for dependencies..."

# Find out the library dependencies
# (i.e. $LOCAL or $MACPORTS), then loop until no changes.
a=1
nfiles=`ls ${ROOT}$APPLIB | wc -l`
alllibs=""
endl=true
while $endl; do
	#echo -e "\033[1mLooking for dependencies.\033[0m Round" $a
	libs="`otool -L ${ROOT}$APPLIB/* $LIBADD ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/* ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx ${ROOT}$APPLIB/python*/site-packages/*/*.so 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep -e '\('$MACPORTS'\|'@rpath'\)' | sort | uniq`"
	# The following is to check that we don't take libX11 with us (which may happen if ImageMagick is installed without +no_x11)
	#for l in  ${ROOT}$APPLIB/* $LIBADD ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/* ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx; do
	#    otool -L $l | grep /opt/local/lib/libX11 && echo "Error: $l links with libX11, please fix this!"
	#done
	if [ -n "$libs" ]; then
          for l in $libs; do
            case $l in
		$MACPORTS/lib/*)
		    if [ ! -f ${ROOT}$APPLIB/`basename $l` ]; then
			cp -f $l ${ROOT}$APPLIB
			chmod +w ${ROOT}$APPLIB/`basename $l`
		    fi
		    ;;
		$MACPORTS/Library/Frameworks/*)
		    if [ ! -f ${ROOT}$APPLIB/`basename $l` ]; then
			cp -f $l ${ROOT}$APPLIB
			chmod +w ${ROOT}$APPLIB/`basename $l`
		    fi
		    #f=`echo $l|sed -e "s@$MACPORTS@@"| awk -F / '{print $4}'`
		    #ditto "$MACPORTS/Library/Frameworks/$f" "${ROOT}$FRAMEWORKS/$f"
		    ;;
	    esac
	  done
	  alllibs="`echo $alllibs $libs | awk -v OFS="\n" '$1=$1' | sort | uniq`"
	fi
	let "a+=1"	
	nnfiles=`ls ${ROOT}$APPLIB | wc -l`
	if [ $nnfiles = $nfiles ]; then
		endl=false
	else
		nfiles=$nnfiles
	fi
done

# TuttleOFX should be built universal
if false; then
arch=`uname -m`
case "$arch" in
    i386|x86_64)
	echo "Info: thinning libraries"
	for f in  ${ROOT}$APPLIB/* $LIBADD ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/* ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx ${ROOT}$APPLIB/python*/site-packages/*/*.so; do
	    lipo -thin $arch $f -output ${f}.i386 && mv  ${f}.i386  ${f} && echo " ${f} done"
	done
	;;
esac
fi

echo "Info: change library names..."

# all the libraries were copied, now change the names...
for l in $alllibs; do
    case $l in
	@rpath/*)
	    changes="$changes -change $l $APPLIB/`basename $l`"
	    ;;
	$MACPORTS/lib/*)
	    changes="$changes -change $l $APPLIB/`basename $l`"
	    ;;
	$MACPORTS/Library/Frameworks/*)
	    changes="$changes -change $l $APPLIB/`basename $l`"
	    #f=`echo $l|sed -e "s@$MACPORTS/Library/Frameworks@@"`
	    #changes="$changes -change $l ${ROOT}$FRAMEWORKS/$f"
	    ;;
    esac
done

for f in  ${ROOT}$APPLIB/* $LIBADD ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/* ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx; do
  # avoid directories
  if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
    if ! install_name_tool $changes $f; then
      echo "Error: 'install_name_tool $changes $f' failed"
      exit 1
    fi
  fi
done

echo "Info: strip extra symbols from OFX plugins..."

SYMBOLS="/tmp/osxSymbols$$"
cat > $SYMBOLS <<EOF
_OfxGetPlugin
_OfxGetNumberOfPlugins
EOF

for f in   ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx; do
  strip -s $SYMBOLS -u $f 2>&1 >/dev/null
done
rm -f $SYMBOLS

for f in ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/*; do
  if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
    strip $f 2>&1 >/dev/null
  fi
done

for f in  ${ROOT}$APPLIB/* $LIBADD; do
  if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
    strip -x $f 2>&1 >/dev/null
  fi
done

echo "Info: obfuscate MacPorts paths..."

# and now, obfuscate all the default paths in dynamic libraries
# and ImageMagick modules and config files
# so that macports is never referenced, even if it's installed.

# generate a pseudo-random string which has the same length as $MACPORTS
RANDSTR="3R2b1RG2qD3567t8hC3b93R2b1RG2qD356R7bUU6jiFvqrPy6zLVPwIC3b97t8h"
MACRAND=${RANDSTR:0:${#MACPORTS}}
find ${ROOT}$APPLIB -type f -exec sed -e "s@$MACPORTS@$MACRAND@g" -i "" {} \;
for f in  ${ROOT}$APPLIB/* $LIBADD ${ROOT}$APPBIN/sam* ${ROOT}$APPBIN/example/* ${ROOT}$APPOFX/*.ofx.bundle/Contents/MacOS/*.ofx; do
    [ -f "$f" ] && sed -e "s@$MACPORTS@$MACRAND@g" -i "" "$f"
done

if test `uname -r | cut -f 1 -d . ` -le 11; then
    # Snow Leopard's probuctbuild doesn't have the --root option
    echo "Info: building a tar.gz file from $ROOT"
    tgzfile=`pwd`/TuttleOFX${PKGEXT}.tar.gz
    (cd ${ROOT} && tar zcf $tgzfile .)
    COMMAND="productbuild --root /where/you/extracted/the/tgzfile / --identifier eu.mikrosimage.TuttleOFX${PKGEXT} TuttleOFX${PKGEXT}.pkg"
    echo "#!/bin/sh" > TuttleOFX${PKGEXT}.sh
    echo "$COMMAND" >> TuttleOFX${PKGEXT}.sh
    chmod +x TuttleOFX${PKGEXT}.sh
    echo "on a recent OSX (>=10.8), please unpack the tar.gz file and execute:"
    echo "$COMMAND"
    echo "(for convenience, the TuttleOFX${PKGEXT}.sh script was created, which contains this command)"
    echo "Info: output is in TuttleOFX${PKGEXT}.tar.gz and TuttleOFX${PKGEXT}.sh"
    echo 'Info: You can list the package contents using "tar ztvf TuttleOFX${PKGEXT}.tar.gz"'
else
    echo "Info: building a package from $ROOT"


    echo "Info: building the package TuttleOFX${PKGEXT}.pkg"

    productbuild --root ${ROOT} / --identifier eu.mikrosimage.TuttleOFX${PKGEXT} TuttleOFX${PKGEXT}.pkg
    echo "Info: output is in TuttleOFX${PKGEXT}.pkg"
    echo 'Info: You can list the package contents using "pkgutil --payload-files TuttleOFX${PKGEXT}.pkg"'
fi

echo "Info: cleaning..."
rm -rf $ROOT

echo 'Info: done!'
