"""
See BENTO_BUILD.txt.

Caveats:

    - no automatic detection for BLAS/LAPACK/etc... You need to set it up
      manually for now (except on Mac OS X and Debian/Ubuntu). The upside is
      that it is extremely easy to do so
    - bento is still in flux, and some things may changes between releases.
"""
    
import os
import sys
import shutil

# Ugly but necessary hack: import numpy here so that wscript in sub directories
# will see this numpy and not an already installed one
import __builtin__
__builtin__.__NUMPY_SETUP__ = True

from bento.installed_package_description \
    import \
        InstalledSection
from bento.commands import hooks
from bento.commands.extras.waf \
    import \
        ConfigureWafContext, BuildWafContext, register_options

import waflib

def check_blas_lapack(conf):
    conf.env.HAS_CBLAS = False
    if sys.platform == "win32":
        mkl_libs = "mkl_lapack95,mkl_blas95,mkl_intel_c,mkl_intel_thread,mkl_core,libiomp5md".split(",")
        mkl_base = r"C:\Program Files\Intel\Compiler\11.1\051"
        conf.env.INCLUDES.append("%s\mkl\include" % mkl_base)
        conf.env.LIBPATH.extend(["%s\mkl\ia32\lib" % mkl_base,
                                 "%s\lib\ia32" % mkl_base])

        try:
            conf.check_cc(lib=mkl_libs, msg="Checking for MKL (CBLAS)",
                          uselib_store="CBLAS")
            conf.env.HAS_CBLAS = True

            conf.check_cc(lib=mkl_libs, msg="Checking for MKL (LAPACK)",
                          uselib_store="LAPACK")
            conf.env.HAS_LAPACK = True
        except waflib.Errors.ConfigurationError:
            pass

    elif sys.platform == "darwin":
        try:
            conf.check(framework="Accelerate", msg="Checking for framework Accelerate", uselib_store="CBLAS")
            conf.env.HAS_CBLAS = True

            conf.check(framework="Accelerate", msg="Checking for framework Accelerate", uselib_store="LAPACK")
            conf.env.HAS_LAPACK = True
        except waflib.Errors.ConfigurationError:
            pass
    else:
        try:
            conf.check_cc(lib=["cblas", "atlas"], uselib_store="CBLAS")
            conf.env.HAS_CBLAS = True

            conf.check_cc(lib=["lapack", "f77blas", "cblas", "atlas"],
                          uselib_store="LAPACK")
            conf.env.HAS_LAPACK = True
        except waflib.Errors.ConfigurationError:
            pass

    # You can manually set up blas/lapack as follows:
    #conf.env.HAS_CBLAS = True
    #conf.env.LIB_CBLAS = ["cblas", "atlas"]
    #conf.env.HAS_LAPACK = True
    #conf.env.LIB_LAPACK = ["lapack", "f77blas", "cblas", "atlas"]

def remove_flag(name, flag):
    while True:
        if name in flag:
            i = flag.index(name)
            flag.pop(i)
        else:
            break

def remove_flag_postvalue(name, flag):
    while True:
        if name in flag:
            i = flag.index(name)
            flag.pop(i)
            flag.pop(i)
        else:
            break

def remove_flag_prevalue(name, flag):
    while True:
        if name in flag:
            i = flag.index(name)
            flag.pop(i-1)
            flag.pop(i-1)
        else:
            break

@hooks.pre_configure
def pre_configure(context):
    conf = context.waf_context

    conf.load("compiler_c")
    conf.load("python")

    conf.check_python_version((2, 4, 0))
    conf.check_python_headers()
    if sys.platform == "darwin":
        remove_flag_prevalue("ppc", conf.env.CFLAGS_PYEXT)
        remove_flag_prevalue("ppc", conf.env.LINKFLAGS_PYEXT)
        conf.env["MACOSX_DEPLOYMENT_TARGET"] = "10.4"

    if conf.env["CC_NAME"] == "gcc":
        conf.env.CFLAGS_PYEXT.append("-Wfatal-errors")
    check_blas_lapack(conf)

# FIXME: abstract those module gen tasks...
class write_module(waflib.Task.Task):
    color = "CYAN"
    vars = ["CONTENT"]
    def run(self):
        # FIXME: put actual data here
        self.outputs[0].write(self.env.CONTENT)

@waflib.TaskGen.feature("gen_pymodule")
def process_write_config(self):
    if not hasattr(self, "content"):
        raise ValueError("task gen %r expects a 'content' argument" % self.name)
    else:
        self.env.CONTENT = self.content
    output = self.path.find_or_declare(self.target)
    name = getattr(self, "name", None) or self.target

    bento_context = self.bld.bento_context
    b_output = bento_context.build_node.make_node(output.bldpath())
    bento_context.outputs_registry.register_outputs(
        "gen_pymodule", name, [b_output], bento_context.build_node, "$sitedir")

    tsk = self.create_task("write_module")
    tsk.set_outputs(output)
    return tsk

@hooks.pre_build
def pre_build(context):
    bld = context.waf_context

    def iregistrer(category, name, nodes, from_node, target_dir):
        source_dir = os.path.join("$_srcrootdir", from_node.bldpath())
        files = [n.path_from(from_node) for n in nodes]
        return InstalledSection.from_source_target_directories(category, name, source_dir, target_dir, files)
    context.isection_registry.register_category("gen_pymodule", iregistrer)
    context.outputs_registry.register_category("gen_pymodule", "pythonfiles")
    bld(features="gen_pymodule",
        target="numpy/__config__.py",
        content="""\
def show():
    pass
""",
        always=True)
    bld(features="gen_pymodule",
        target="numpy/version.py",
        content="""\
git_revision = ""
version = ""
""",
        always=True)

@hooks.options
def options(context):
    register_options(context)

@hooks.startup
def startup(context):
    context.register_context("configure", ConfigureWafContext)
    context.register_context("build", BuildWafContext)
