# Last Change: Sat Nov 01 11:00 PM 2008 J
# vim:syntax=python

import os
from os.path import join as pjoin, splitext

from numscons import GetNumpyEnvironment
from numscons import CheckCBLAS, CheckF77BLAS, CheckF77LAPACK,\
                                  CheckCLAPACK, IsVeclib, IsAccelerate, \
                                  IsATLAS, GetATLASVersion, CheckF77Clib
from numscons import write_info

from scons_support import do_generate_interface, do_generate_fake_interface, \
                          generate_interface_emitter

#from scons_support import CheckBrokenMathlib, define_no_smp, \
#    generate_config_header, generate_config_header_emitter

env = GetNumpyEnvironment(ARGUMENTS)
env.Tool('f2py')

# XXX: handle cblas wrapper for complex (check in numpy.scons or here ?)
env.AppendUnique(F2PYOPTIONS = '--quiet')

env['BUILDERS']['haha'] = Builder(action = do_generate_interface,
                                  emitter = generate_interface_emitter)

env['BUILDERS']['hihi'] = Builder(action = do_generate_fake_interface,
                                  emitter = generate_interface_emitter)

#if os.name == 'nt':
#    # NT needs the pythonlib to run any code importing Python.h, including
#    # simple code using only typedef and so on, so we need it for configuration
#    # checks
#    env.AppendUnique(LIBPATH = [get_pythonlib_dir()])

fenv = env.Clone()

#=======================
# Starting Configuration
#=======================
config = env.NumpyConfigure(custom_tests = {'CheckCBLAS' : CheckCBLAS,
                                            'CheckCLAPACK' : CheckCLAPACK})

#-------------------------
# Checking cblas/clapack
#-------------------------
if config.CheckCBLAS():
    has_cblas = 1
else:
    has_cblas = 0
if has_cblas:
    if IsATLAS(env, 'cblas'):
        version = GetATLASVersion(env)
        env.Append(CPPDEFINES = [('ATLAS_INFO', '"\\"%s"\\"' % version)])
    else:
        env.Append(CPPDEFINES = [('NO_ATLAS_INFO', 1)])

if config.CheckCLAPACK():
    has_clapack = 1
else:
    has_clapack = 0

config.Finish()
write_info(env)

#---------------------------
# Checking F77 blas/lapack
#---------------------------
fconfig = fenv.NumpyConfigure(custom_tests = {'CheckBLAS' : CheckF77BLAS,
                                              'CheckLAPACK' : CheckF77LAPACK,
                                              'CheckF77Clib' : CheckF77Clib})

if not fconfig.CheckF77Clib():
    raise RuntimeError("Could not check F/C runtime library for %s/%s, " \
                       "contact the maintainer" % (fenv['CC'], fenv['F77']))

st = fconfig.CheckBLAS(check_version = 1)
if not st:
    raise RuntimeError("no blas found, necessary for linalg module")
if IsATLAS(fenv, 'blas'):
    version = GetATLASVersion(fenv)
    env.Append(CPPDEFINES = [('ATLAS_INFO', '"\\"%s"\\"' % version)])
else:
    env.Append(CPPDEFINES = [('NO_ATLAS_INFO', 1)])

st = fconfig.CheckLAPACK()
if not st:
    raise RuntimeError("no lapack found, necessary for linalg module")
fconfig.Finish()
write_info(fenv)


#==========
#  Build
#==========
#------------
#   fblas
#------------
fenv.FromFTemplate('fblas.pyf', 'fblas.pyf.src')
source = ['fblas.pyf']
if IsVeclib(fenv, 'blas') or IsAccelerate(fenv, 'blas'):
    source.append(pjoin('src', 'fblaswrap_veclib_c.c'))
else:
    source.append(pjoin('src', 'fblaswrap.f'))
fenv.NumpyPythonExtension('fblas', source)

#------------
#   cblas
#------------
if has_cblas:
    env.haha('cblas', 'generic_cblas.pyf')
else:
    env.hihi('cblas', 'generic_cblas.pyf')
env.NumpyPythonExtension('cblas', source = 'cblas.pyf')

#------------
#   flapack
#------------
yop = fenv.haha('flapack', 'generic_flapack.pyf')
# XXX: automatically scan dependency on flapack_user_routines.pyf ?
fenv.Depends(yop, 'flapack_user_routines.pyf')
fenv.NumpyPythonExtension('flapack', 'flapack.pyf')

#------------
#   clapack
#------------
if has_clapack:
    env.haha('clapack', 'generic_clapack.pyf')
else:
    env.hihi('clapack', 'generic_clapack.pyf')
env.NumpyPythonExtension('clapack', source = 'clapack.pyf')

#----------------
#   _flinalg
#----------------
flinalg_fsrc = [pjoin('src', i) for i in ['det.f', 'lu.f']]
flinalg_src = fenv.F2py(pjoin('src', '_flinalgmodule.c'), flinalg_fsrc)

fenv.NumpyPythonExtension('_flinalg', source = flinalg_src + flinalg_fsrc)

#----------------
# calc_lwork:
#----------------
calc_fsrc = [pjoin('src', 'calc_lwork.f')]
calc_src = env.F2py(pjoin('src', 'calc_lworkmodule.c'), calc_fsrc)
fenv.NumpyPythonExtension('calc_lwork', calc_src + calc_fsrc)

#--------------
# Atlas version
#--------------
atlas_env = env.Clone()
if not IsATLAS(env, 'cblas'):
    atlas_env.AppendUnique(CPPDEFINES = "NO_ATLAS_INFO")
atlas_env.NumpyPythonExtension('atlas_version', 'atlas_version.c')
