import sys, os, subprocess, platform

EnsureSConsVersion(0, 98)

# Colours
colours = {}
colours['cyan']   = '\033[96m'
colours['purple'] = '\033[95m'
colours['blue']   = '\033[94m'
colours['green']  = '\033[92m'
colours['yellow'] = '\033[93m'
colours['red']    = '\033[91m'
colours['end']    = '\033[0m'

# If the output is not a terminal, remove the colours.
if not sys.stdout.isatty():
   for key, value in colours.items():
      colours[key] = ''

compile_source_message = '%sCompiling %s==> %s$SOURCE%s' % \
   (colours['blue'], colours['purple'], colours['yellow'], colours['end'])

link_program_message = '%sLinking Program %s==> %s$TARGET%s' % \
   (colours['cyan'], colours['purple'], colours['yellow'], colours['end'])

link_library_message = '%sLinking Library %s==> %s$TARGET%s' % \
   (colours['cyan'], colours['purple'], colours['yellow'], colours['end'])

ranlib_library_message = '%sRanlib Library %s==> %s$TARGET%s' % \
   (colours['cyan'], colours['purple'], colours['yellow'], colours['end'])

install_message = '%sInstalling %s==> %s$TARGET%s'% \
   (colours['green'], colours['purple'], colours['yellow'], colours['end']) 

# CUSTOMISE THE ENVIRONMENT HERE.
env = Environment(ENV=os.environ,
                  tools=['default', 'pcutest', 'dist'],
                  toolpath=['StGermain/pcu/script', 'script'])

# Check if scons is launched with detail flag.
detail = ARGUMENTS.get('detail', 0)
Help("""
SCons Build Options:
    Type: './scons.py detail=1' to build Underworld showing full detail non-coloured stdout" 
""" )

# If detail flag is not set, let's use our own build strings.
if not int(detail):
    env['CXXCOMSTR'] = compile_source_message
    env['CCCOMSTR'] = compile_source_message
    env['SHCCCOMSTR'] = compile_source_message
    env['SHCXXCOMSTR'] = compile_source_message
    env['ARCOMSTR'] = link_library_message
    env['RANLIBCOMSTR'] = ranlib_library_message
    env['SHLINKCOMSTR'] = link_library_message
    env['LINKCOMSTR'] = link_program_message
    env['INSTALLSTR'] = install_message

# Needed for Darwin.
env['_abspath'] = lambda x: File(x).abspath

# Ludicrous-speed!
env.Decider("MD5-timestamp")

# Load configuration.
values = {}
if(not os.path.isfile('config.cfg')):
   print('Error: \'config.cfg\' file not found.  The configuration script (configure.py) must be run successfully before you can build (via scons.py).')
   sys.exit()

exec(open("config.cfg").read(), globals(), values)
env._dict.update(values)

# Set LIBPATH and RPATH for libraries
if env['prefix'] == env.GetLaunchDir():
   env['RPATH'] += [os.path.join(env['prefix'], env['build_dir'], "lib")]
   env['LIBPATH'] = [os.path.join(env['prefix'], env['build_dir'], "lib")] + env['LIBPATH']
else:
   env['RPATH'] += [os.path.join(env['prefix'], "lib")]
   env['LIBPATH'] = [os.path.join(env['prefix'], "lib")] + env['LIBPATH']

# Check if we're using 64bit.
if platform.architecture()[0] == '64bit':
    env.AppendUnique(CPPDEFINES=[('SYSTEM_SIZEOF_LONG', 8)])

# Need to manipulate the build directory to keep SCons happy. Because of SCons' target
# rules we need to make the build directory a default target.
env["build_dir"] = os.path.join(env.GetLaunchDir(), env["build_dir"])
env["prefix"] = os.path.join(env.GetLaunchDir(), env["prefix"])
env["INST_BUILD_DIR"] = env["build_dir"]
env["INST_PREFIX"] = env["prefix"]
env.Default(env["build_dir"])

# Add the build directory's include path.
env.AppendUnique(CPPPATH=env['build_dir'] + '/include')

# Need to define the extension for shared libraries as well
# as the library directory.
ext = env['ESCAPE']('"' + env['SHLIBSUFFIX'][1:] + '"')
lib_dir = env['ESCAPE']('"' + os.path.abspath(env['build_dir']) + '/lib' + '"')
env.AppendUnique(CPPDEFINES=[('MODULE_EXT', ext), ('LIB_DIR', lib_dir)])

# Include the library path.
env.AppendUnique(LIBPATH=env['build_dir'] + '/lib')
env.AppendUnique(RPATH=env.Dir(env['build_dir'] + '/lib').abspath)

# If we have no shared libraries, include a pre-processor definition to
# prevent modules from trying to load dynamically.
if not env['shared_libs']:
    env.AppendUnique(CPPDEFINES=['NOSHARED'])

# Need to insert some 'HAVE_*' definitions based on what packages we
# found during configuration.
if 'HAVE_HDF5' in env['CPPDEFINES']:
    env.AppendUnique(CPPDEFINES=["READ_HDF5", "WRITE_HDF5"])

# If we were given a prefix other than the default, tell StGermain where to
# find XML include files.
if env['prefix'] != env.GetLaunchDir():
    env.AppendUnique(CPPDEFINES=[('STG_INCLUDE_PATH', env['ESCAPE']('"' + env['prefix'] + '/lib/StGermain"'))])

# Make sure 'install' has a proper target.
env.Alias("install", env["prefix"])

# INSERT TARGETS HERE.

# Make a copy of the config.log and config.cfg in the build_dir
dir = Dir(env['build_dir']).abspath
if not os.path.exists(dir):
   os.makedirs(dir)

env.Install('share/underworld', 'config.log')
env.Install('share/underworld', 'config.cfg')

import os
# install python API files
for root, dirs, files in os.walk(".."):
    path = root.split(os.sep)
    basepath = os.sep.join(path[1:])
    if basepath in ['libUnderworld']: continue  # we'll do this below to avoid install chaff
    for file in files:
        if file.endswith(".py"):
            env.Install(os.path.join(env["prefix"],basepath), os.path.join(root, file))
# install python bindings C-API files
for root, dirs, files in os.walk("./libUnderworldPy"):
    path = root.split(os.sep)
    basepath = os.sep.join(path[1:])
    for file in files:
        if file.endswith(".py"):
            env.Install(os.path.join(env["prefix"],'libUnderworld','libUnderworldPy'), os.path.join(root, file))
env.Install(os.path.join(env["prefix"],'libUnderworld'), '__init__.py')
Export('env')

SConscript('StGermain/SConscript',
           variant_dir=env['build_dir'] + '/StGermain',
           duplicate=0)
env.Prepend(LIBS=['pcu'])
env.Prepend(LIBS=['StGermain'])

SConscript('StgDomain/SConscript',
           variant_dir=env['build_dir'] + '/StgDomain',
           duplicate=0)
env.Prepend(LIBS=['StgDomain'])

SConscript('StgFEM/SConscript',
           variant_dir=env['build_dir'] + '/StgFEM',
           duplicate=0)
env.Prepend(LIBS=['StgFEM'])

SConscript('PICellerator/SConscript',
           variant_dir=env['build_dir'] + '/PICellerator',
           duplicate=0)
env.Prepend(LIBS=['PICellerator'])

SConscript('Underworld/SConscript',
           variant_dir=env['build_dir'] + '/Underworld',
           duplicate=0)
env.Prepend(LIBS=['Underworld'])

SConscript('gLucifer/SConscript',
       variant_dir=env['build_dir'] + '/gLucifer',
       duplicate=0)
env.Prepend(LIBS=['gLucifer'])

SConscript('Solvers/SConscript',
       variant_dir=env['build_dir'] + '/Solvers',
       duplicate=0)
env.Prepend(LIBS=['Solvers'])

# lets finally build the wrappers
SConscript('libUnderworldPy/SConscript',
           variant_dir=env['build_dir'] + '/libUnderworldPy',
           duplicate=0)
env.Prepend(LIBS=['libUnderworldPy'])
