#! /usr/bin/env python
# encoding: UTF-8
# Peter Forai
# Thomas Nagy, 2008

"""
Demonstrates how to create a c++ app that runs python scripts

Useful for apps providing script extensions
"""

VERSION='0.0.1'
APPNAME='swig_test'
top = '.'
out = 'build'

def options(opt):
	opt.load('g++ python')

def configure(conf):
	conf.load('g++ python')
	conf.check_python_version((2,4,2))
	conf.check_python_headers()

	conf.load('swig')
	if conf.check_swig_version() < (1, 2, 27):
		conf.fatal('this swig version is too old')

	try:
		conf.load('java')
		# on mandriva, at least, libjvm.so is difficult to find
		#conf.env.LIBPATH_JAVA = "/usr/lib/jvm/java-1.6.0-sun-1.6.0.13/jre/lib/amd64/server/"
		conf.check_jni_headers()
		conf.env.HAVE_JAVA = True
	except conf.errors.ConfigurationError:
		conf.env.HAVE_JAVA = False

def build(bld):

	# embedding
	#
	# use swig_flags = '-c++ -python -dump_classes' for debugging

	obj = bld(
		features = 'cxx cxxprogram pyembed',
		source = 'embed/src1.cpp embed/bind.swig',
		target = 'embed/embed_demo',
		swig_flags = '-c++ -python -Wall',
		includes = '. embed')


	# extending
	#
	# be careful that the .py produced by swig is mandatory for using the library
	#
	# it is possible to disable 'mylib', and to add extend/a.cpp
	# to the source of extend/python/_test_swig_waf and remove use

	bld(
		features = 'cxx cxxshlib',
		source = 'extend/a.cpp',
		target = 'extend/mylib',
		includes = 'extend',
		export_includes = 'extend',
		vnum = '1.2.3',
		name = 'mylib')

	bld(
		features = 'cxx cxxshlib pyext',
		source = 'extend/python/test_swig_waf.i',
		target = 'extend/python/_test_swig_waf',
		swig_flags = '-c++ -python -Wall',
		includes = 'extend',
		vnum = '1.2.3',
		use  = 'mylib')

	bld.install_files('${PREFIX}/lib', 'extend/python/test_swig_waf.py')

	bld.add_post_fun(exec_test_python)

	# some java stuff
	if not bld.env.HAVE_JAVA:
		return

	from waflib.extras import swig

	srcdir = bld.path.get_bld().make_node('extend/java/hmm') # destination for generated java file (without the packages!)

	#""" # BEGIN BLOCK 1
	d = bld.path.make_node('extend/java')
	javanodes = [d.find_or_declare(x) for x in 'A.java  test_swig_waf.java  test_swig_wafJNI.java'.split()]
	dec = bld.tools['swig'].swigf
	#@dec <- python 2.3 does not support the @decorator notation
	def swig_java(tsk):
		tsk.outputs.extend(javanodes)
	bld.tools['swig'].swigf(swig_java)
	""" # END BLOCK 1
	#"""# do not remove





	bld(
		features   = 'cxx cxxshlib',
		source     = 'extend/java/test_swig_waf.i',
		target     = 'extend/java/_test_swig_waf',
		swig_flags = '-c++ -java -package foo.bar.pouet',
		includes   = 'extend',
		vnum       = '1.2.3',
		uselib     = 'JAVA',
		use        = 'mylib')

	#""" # BEGIN BLOCK 2
	for x in javanodes:
		bld(rule='cp ${SRC} ${TGT}', source=x,
			target=srcdir.make_node('foo/bar/pouet/' + x.name), before=['javac'], after=['swig'])
	""" # END BLOCK 2

	def move_java_files(task):
		import os, shutil
		from waflib import Utils

		node = srcdir.make_node('foo/bar/pouet/')
		node.mkdir()
		orig = task.inputs[0].parent.get_bld().abspath()
		files = Utils.listdir(orig)
		for x in files:
			if x.endswith('.java'):
				# create a node in the directory we want to
				j = node.make_node(x) # create a node
				shutil.copy2(orig + os.sep + x, j.abspath()) # create the physical file for the node
				j.sig = Utils.h_file(j.abspath()) # update the node signature
	# depend on the .i file to make sure the .java files are copied after swig is executed
	bld(name='move_and_read', rule=move_java_files, source='extend/java/test_swig_waf.i', after=['swig'], before=['javac'])
	#"""


	bld(rule='cp ${SRC} ${TGT}', source=bld.path.find_resource('extend/java/Foo.java'),
		target=srcdir.make_node('foo/bar/pouet/Foo.java'), before=['javac'], after=['swig'])

	tmp = bld.path.get_bld().make_node('maha')

	bld(features   = 'javac jar',
		srcdir     = srcdir,
		sourcepath = [],
		outdir     = tmp, # we do need another folder here
		basedir    = tmp,
		destfile   = 'maha.jar'
		)

	bld.add_post_fun(exec_test_java)

	#########################################
	# listing the java nodes is required to ensure the swig task
	# is executed whenever the java files are removed from
	# the build directory
	#
	# to list the java files automatically, comment the starting character '#' in the lines "BEGIN BLOCK 1" and "BEGIN BLOCK 2"


def exec_test_java(bld):
	try:
		bld.cmd_and_log('LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/extend/java:build/extend java -classpath "build/maha.jar:." foo.bar.pouet.Foo')
	except:
		pass

def exec_test_python(bld):
	import os, stat
	try:
		import subprocess
		proc = subprocess.Popen('''
PYTHONPATH=$PYTHONPATH:build/extend/python
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:build/extend/python:build/extend
python -c "import test_swig_waf; a=test_swig_waf.A(); print 'Testing: a.add(2, 3) ->', a.add(2, 3)"
'''.replace('\n', ' '), shell=True)
		proc.wait()
	except:
		pass

	# why does this fail now on mandriva???
	try:
		os.stat('build/embed/embed_demo')
		bld.cmd_and_log('PYTHONPATH=$PYTHONPATH:build/embed/ build/embed/embed_demo')
	except:
		pass

