#-*- Python -*-

# SConsBuilder Project File
#
# This file will be executed after the initial build environment is created
# but before it is finalized.
#
# - Available variables for import -
#
# init_env - Initial build environment
#
# - Available environment variables -
#
#  init_env['BUILD_DIR'] - building directory
#  init_env['OBJ_DIR']   - building subdirectory for object files, etc.
#
# You should at least declare following init_env variables:
#
# INCLUDE_DIR      - Include directory
# SOURCE_DIRS      - All source directories
# LIB_DIR          - Destination directory for libraries
# BIN_DIR          - Destination directory for executables
# CONFIG_HEADER    - Used for autogenerated configuration header
#                    use None or ConfigHeader()
# PROJECT_PREFIX   - Used for auto-configuration
# SYSTEM_PREFIX    - Used for auto-configuration
# COMPILER_PREFIX  - Used for auto-configuration
# AUTOCONF_PREFIX  - Used for auto-configuration

import sys
import os
import os.path
import datetime
from builder.btools import *

Import('init_env')

BUILD_DIR = init_env['BUILD_DIR']

SOURCE_DIRS = Split("""
#src/core
#src/examples
#src/demo
""")

INCLUDE_DIR = BUILD_DIR + os.sep + 'include'
LIB_DIR = BUILD_DIR + os.sep + 'lib'
BIN_DIR = BUILD_DIR + os.sep + 'bin'

CONFIG_HEADER = ConfigHeader()

# define symbol prefixes

PROJECT_PREFIX = 'SCALN_'
SYSTEM_PREFIX = ''
COMPILER_PREFIX = 'COMPILER_'
AUTOCONF_PREFIX = 'SCALN_'

init_env.Replace(CXXFILESUFFIX='.cpp',
                 INCLUDE_DIR=INCLUDE_DIR,
                 SOURCE_DIRS=SOURCE_DIRS,
                 LIB_DIR=LIB_DIR,
                 BIN_DIR=BIN_DIR,
                 CONFIG_HEADER=CONFIG_HEADER,
                 PROJECT_PREFIX=PROJECT_PREFIX,
                 SYSTEM_PREFIX=SYSTEM_PREFIX,
                 COMPILER_PREFIX=COMPILER_PREFIX,
                 AUTOCONF_PREFIX=AUTOCONF_PREFIX,
                 CPPPATH=SOURCE_DIRS,
                 LIBPATH=[LIB_DIR])

# Setup configuration, conf is created by env.Configure()

def customizeConfiguration(conf):
    # in conf.env is the environment that can be changed
    isWin32 = conf.env['PLATFORM'] == 'win32'

    # Only for local installation 
    INC = os.path.join('include', os.getenv('HOME'), 'local-install', 'include')
    LIB = os.path.join('.', os.getenv('HOME'), 'local-install', 'lib')

    if os.path.exists(INC):
        conf.env.Append(CPPPATH = [INC])
    if os.path.exists(LIB):
        conf.env.Append(LIBPATH = [LIB])

    # On Windows append win32tools/include to CPPPATH
    #                   win32tools/lib to LIBPATH
    #                   win32tools/bin to PATH
    if isWin32:
        win32toolsDir = os.path.join(conf.env.Dir('#').abspath, 'win32tools')
        if os.path.exists(win32toolsDir):
            conf.env.Append(CPPPATH = [os.path.join(win32toolsDir, 'include')])
            conf.env.Append(LIBPATH = [os.path.join(win32toolsDir, 'lib')])
            conf.env.PrependENVPath('PATH', os.path.join(win32toolsDir, 'bin'))

    conf.env.Tool('textfile')

    # init lex tool
    conf.env.Tool('lex')
    # check lex tool

    # Get git revision
    import subprocess
    import types
    gitRevision = '<unknown>'
    conf.env.Replace(GIT_REVISION=gitRevision)
    try:
        osenv={}
        for k, v in os.environ.iteritems():
            if type(v) is not types.StringType:
                osenv[k] = str(v)
            else:
                osenv[k] = v

        p = subprocess.Popen(["git","rev-parse","--short=10","HEAD"],
                             env=osenv,
                             stdout=subprocess.PIPE)
        gitRevision = p.communicate()[0].strip()
        if p.returncode == 0:
            conf.env.Replace(GIT_REVISION=gitRevision)
        del osenv
    except OSError, e:
        print >>sys.stderr, "Git execution failed:", e

    print "* Building from Git Repository Revision: %s" % gitRevision

    if not conf.CheckCCompiler():
        print >>sys.stderr, 'Error: Could not run C/C++ compiler'
        Exit(1)

    sizeof_longdouble = conf.CheckTypeSize('long double')
    conf.env.Replace(SIZEOF_LONGDOUBLE=sizeof_longdouble)


RegisterConfigurationCustomizer(customizeConfiguration)

# Customize final environment

def finalizeEnvironment(env):
    # Evaluate building hierarchy
    Export('env')

    # setup install directories

    INSTALL_DIR = env['prefix']

    INSTALL_INCLUDE_DIR = os.path.join(INSTALL_DIR, 'include')
    INSTALL_LIB_DIR     = os.path.join(INSTALL_DIR, 'lib')
    INSTALL_BIN_DIR     = os.path.join(INSTALL_DIR, 'bin')

    INSTALL_DIRS = [INSTALL_INCLUDE_DIR,
                    INSTALL_LIB_DIR,
                    INSTALL_BIN_DIR]

    env.Replace(INSTALL_INCLUDE_DIR = INSTALL_INCLUDE_DIR,
                INSTALL_LIB_DIR = INSTALL_LIB_DIR,
                INSTALL_BIN_DIR = INSTALL_BIN_DIR,
                INSTALL_DIRS = INSTALL_DIRS)

    # process all source directories

    for srcDir in SOURCE_DIRS:
        buildDir = srcDir
        if buildDir.startswith('#'):
            buildDir = buildDir[1:]

        buildDir = os.path.join(env['OBJ_DIR'], buildDir)

        VariantDir(buildDir, srcDir, duplicate=0)
        SConscript(os.path.join(buildDir, 'SConscript'))

    # Alternate method to setup build directory :
    # SConscript('src' + os.sep + 'SConscript',
    #            build_dir=env['BUILD_DIR'],
    #            src_dir=env['SRC_DIR'],
    #            duplicate=0)

    # build documentation

    DOXYGEN_OUTPUT_DIR = '#doc/doxygen'
    DOXYGEN_CONFIG_FILE = '#doc/Doxyfile'

    env.Command(env.Dir(DOXYGEN_OUTPUT_DIR), DOXYGEN_CONFIG_FILE,
                "doxygen $SOURCES",
                ENV = {'DOXYGEN_OUTPUT_DIR' : env.Dir(DOXYGEN_OUTPUT_DIR).abspath,
                       'DOXYGEN_INPUT_DIR' : env.Dir('#src').abspath
                       })
    env.Alias('doc', env.Dir(DOXYGEN_OUTPUT_DIR))
    env.AlwaysBuild(env.Dir(DOXYGEN_OUTPUT_DIR))
    Help("""doc:            Generate doxygen documentation""")

    # default targets

    Default(env['BUILD_DIR'])
    #Default(env['INCLUDE_DIR'])

    # install targets

    env.Alias('install', INSTALL_DIR)

    # Don't bother computing the MD5 checksum of a file (to see whether the
    # contents of a file have changed) if the file's timestamp has not changed.
    # See: http://www.scons.org/doc/HTML/scons-user/c824.html#AEN944
    env.Decider('MD5-timestamp')

RegisterEnvironmentFinalizer(finalizeEnvironment)
