# vim: set filetype: py

Import('dev source_path setLuaEnv')

targets = []
build_path = dev.get_build_path(source_path)

import os.path

def runCommand(cmd):
	import subprocess
	try:
		p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
		(output, err) = p.communicate()
		return output
	except Exception as e:
		print(e)
		return ""

def getRbConf(name):
	return runCommand([dev.env['ruby'], '-rmkmf', '-e', "print RbConfig.expand('$(" + name + ")')"])

def buildRbModule():
	env = dev.env.Clone()
	conf = Configure(env, conf_dir = dev.get_build_path('.sconf_temp'), log_file = dev.get_build_path('config.log'), clean = False, help = False)

	if not runCommand([dev.env['ruby'], '-v']):
		print("Ruby not found, skipping ruby module")
		return

	env.Append(SWIGFLAGS=['-c++','-Wall','-ruby','-autorename'])

	import distutils.sysconfig
	
	libdir = getRbConf("libdir")
	if not libdir:
		print("Ruby libdir not found, skipping ruby module")
		return 
	
	incdir = getRbConf("rubyhdrdir")
	if not incdir:
		print("Ruby hdrdir not found, skipping ruby module")
		return

	arch = getRbConf("arch")
	if not arch:
		print("Ruby arch not found, skipping ruby module")
		return

	soname = getRbConf("RUBY_SO_NAME")
	if not soname:
		print("Ruby RUBY_SO_NAME not found, skipping ruby module")
		return

	env.Append(LIBPATH=[libdir])
	env.Append(CPPPATH=['#', incdir, os.path.join(incdir, arch)])
	env.Append(LIBS=[soname, 'adchpp'])
		
	if not conf.CheckCHeader('ruby.h'):
		print("ruby.h not found, skipping ruby module")
		conf.Finish()
		return
	conf.Finish()

	ruby_wrap = dev.get_build_path(source_path) + 'ruby_wrap.cxx'

	f = env.CFile(target=ruby_wrap, source='ruby.i')
	
	doc_path = env.Dir(dev.get_target(source_path, "doc/")).path
	env["DOCPATH"] = doc_path
	# TODO make it not rebuild every time...
	# docs = env.Command(doc_path + "/index.html", ruby_wrap, "rdoc -o \"$DOCPATH\" $SOURCES")

	
	if '_DEBUG' in env['CPPDEFINES']:
		env['CPPDEFINES'].remove('_DEBUG')

	rb = env.SharedLibrary(dev.get_target(source_path, 'rbadchpp'), [f],
						SHLIBPREFIX='')

	targets.append(rb)

def buildPyModule():

	print('swig/SConscript > buildPyModule needs updates -> disabled for now.')
	return

	import sys

	env, target, sources = dev.prepare_build(source_path, '_pyadchpp', 'python.i')
	env.Append(SWIGFLAGS=['-c++','-threads','-Wall','-python', '-O', '-modern', '-features', 'autodoc=1'])
	env['SWIGOUTDIR'] = Dir(dev.get_build_path('bin'))

	version = sys.version[0] + sys.version[2]
	
	if version not in ('25','26','27'):
		print('Invalid Python version: ' + version + ' - skipping Python module')
		return

	env.Append(CPPPATH=['#'])
	if '_DEBUG' in env['CPPDEFINES']:
		env['CPPDEFINES'].remove('_DEBUG')
	if '/MDd' in env['CCFLAGS']:
		env['CCFLAGS'].remove('/MDd')
		env['CCFLAGS'].append('/MD')

	if dev.is_win32(): 
		pyprefix = env['python']
		incpath = os.path.join(pyprefix, "include")
		libpath = os.path.join(pyprefix, "libs")

		env.Append(LIBPATH=[libpath])
		env.Append(LIBS=["python"+version])
		env.Append(CPPPATH=[incpath])

	else:
		import distutils
		env.Append(CPPPATH=[distutils.sysconfig.get_python_inc()])
		env.Append(LIBS=['python' + sys.version[0:3]])
		
	env.Append(LIBS=['adchpp'])

	found = False
	for p in env['CPPPATH']:
		if os.path.exists(os.path.join(p, "Python.h")):
			found = True
			break
		
	if not found:
		print ("Python.h not found, not building python extension")
		return
		
	if dev.is_win32():
		env['SHLIBSUFFIX'] ='.pyd'

	pyd = env.SharedLibrary(target, sources, SHLIBPREFIX='')
	targets.append(pyd)

def buildLuaModule(lib,mod,plugin):
	env, target, sources = dev.prepare_build(source_path, lib, mod)

	env['SWIGOUTDIR'] = Dir(dev.get_build_path('bin'))
	
	env.Append(SWIGFLAGS=['-c++','-Wall','-lua'])

	env.Append(LIBS = ['adchpp'])
	if (dev.is_win32() or env['PLATFORM'] == 'cygwin') and 'Bloom' in dev.env['plugins']:
		env.Append(LIBS = ['Bloom'])

	env.Append(CPPPATH=['#'])
	
	# We assume the lua from the script plugin will be used...
	setLuaEnv(env)

	if dev.is_win32():
		env.Append(CPPDEFINES=['LUA_BUILD_AS_DLL=1'])
	else:
		env.Append(CPPDEFINES=['LUA_USE_LINUX=1'])
	
	# on x64, SWIG includes some unsafe pointer conversions that the compiler of course disallows...
	if 'gcc' in env['TOOLS'] and env['arch'] == 'x64':
		env.Append(CPPFLAGS = ['-fpermissive'])

	if plugin:
		env.Replace(UNDEF = '')

	luadchpp = env.SharedLibrary(target, sources, SHLIBPREFIX='')
	targets.append(luadchpp)

def buildPHPModule():
	env, target, sources = dev.prepare_build(source_path, 'php_adchpp', 'php.i')

	if not dev.is_win32():
		print('No Linux support for PHP extensions yet')
		# TODO add Linux support (see TODO below)
		return

	php_path = '#/php/'
	if env['arch'] != 'x86':
		php_path = php_path + env['arch'] + '/'

	if dev.is_win32():
		if env['CC'] == 'cl': # MSVC
			if not os.path.exists(env.File(php_path + 'lib/php5.lib').abspath):
				print('No php5.lib file, skipping PHP')
				return
		else:
			print('Skipping the PHP module, use MSVC or Linux')
			return

	bin_dir = dev.get_build_path('bin')

	env['SWIGOUTDIR'] = Dir(bin_dir)
	env.Append(SWIGFLAGS = ['-c++', '-Wall', '-php'])

	env.Append(CPPPATH = ['#', bin_dir])
	env.Append(LIBS = ['adchpp'])

	if dev.is_win32():
		env.Append(CPPPATH = [php_path + 'include/', php_path + 'include/main/', php_path + 'include/TSRM/', php_path + 'include/Zend/'])
		env.Append(CPPDEFINES = ['WIN32', 'PHP_WIN32=1', 'ZEND_WIN32=1', 'PHP_DEBUG=0', 'ZEND_DEBUG=0', '_USE_32BIT_TIME_T=1'])
		env.Append(LIBPATH = [php_path + 'lib/'])
		env.Append(LIBS = ['php5'])

	else:
		pass # TODO run "php-config --includes"

	php_adchpp = env.SharedLibrary(target, sources, SHLIBPREFIX='')
	targets.append(php_adchpp)

if 'ruby' in dev.env['langs']:
	buildRbModule()

if 'python' in dev.env['langs']:
	if   dev.env['PLATFORM'] == 'win32' and dev.env['arch'] != 'x86':
		print('Skipping Python module because build platform is Windows and ARCH != x86')
	else:
		buildPyModule()

if 'lua' in dev.env['langs']:
	buildLuaModule('luadchpp','lua.i',False)
	if 'Bloom' in dev.env['plugins']:
		buildLuaModule('luadchppbloom','bloom.i',True)

# TODO buildPHPModule()

Return('targets')
