"""custom

Custom builders and methods.

"""

#
# Copyright 2008 VMware, Inc.
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sub license, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice (including the
# next paragraph) shall be included in all copies or substantial portions
# of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#


import os.path
import sys
import subprocess
import modulefinder

import SCons.Action
import SCons.Builder
import SCons.Scanner

import fixes

import source_list

# the get_implicit_deps() method changed between 2.4 and 2.5: now it expects
# a callable that takes a scanner as argument and returns a path, rather than
# a path directly. We want to support both, so we need to detect the SCons version,
# for which no API is provided by SCons 8-P

scons_version = tuple(map(int, SCons.__version__.split('.')))

def quietCommandLines(env):
    # Quiet command lines
    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput
    env['ASCOMSTR'] = "  Assembling $SOURCE ..."
    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..."
    env['CCCOMSTR'] = "  Compiling $SOURCE ..."
    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..."
    env['CXXCOMSTR'] = "  Compiling $SOURCE ..."
    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..."
    env['ARCOMSTR'] = "  Archiving $TARGET ..."
    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..."
    env['LINKCOMSTR'] = "  Linking $TARGET ..."
    env['SHLINKCOMSTR'] = "  Linking $TARGET ..."
    env['LDMODULECOMSTR'] = "  Linking $TARGET ..."
    env['SWIGCOMSTR'] = "  Generating $TARGET ..."
    env['LEXCOMSTR'] = "  Generating $TARGET ..."
    env['YACCCOMSTR'] = "  Generating $TARGET ..."
    env['CODEGENCOMSTR'] = "  Generating $TARGET ..."
    env['INSTALLSTR'] = "  Installing $TARGET ..."


def createConvenienceLibBuilder(env):
    """This is a utility function that creates the ConvenienceLibrary
    Builder in an Environment if it is not there already.

    If it is already there, we return the existing one.

    Based on the stock StaticLibrary and SharedLibrary builders.
    """

    try:
        convenience_lib = env['BUILDERS']['ConvenienceLibrary']
    except KeyError:
        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
        if env.Detect('ranlib'):
            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
            action_list.append(ranlib_action)

        convenience_lib = SCons.Builder.Builder(action = action_list,
                                  emitter = '$LIBEMITTER',
                                  prefix = '$LIBPREFIX',
                                  suffix = '$LIBSUFFIX',
                                  src_suffix = '$SHOBJSUFFIX',
                                  src_builder = 'SharedObject')
        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib

    return convenience_lib


def python_scan(node, env, path):
    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789
    # https://docs.python.org/2/library/modulefinder.html
    contents = node.get_contents()

    # Tell ModuleFinder to search dependencies in the script dir, and the glapi
    # dirs
    source_dir = node.get_dir().abspath
    GLAPI = env.Dir('#src/mapi/glapi/gen').abspath
    path = [source_dir, GLAPI] + sys.path

    finder = modulefinder.ModuleFinder(path=path)
    finder.run_script(node.abspath)
    results = []
    for name, mod in finder.modules.items():
        if mod.__file__ is None:
            continue
        assert os.path.exists(mod.__file__)
        results.append(env.File(mod.__file__))
    return results

python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py'])


def code_generate(env, script, target, source, command):
    """Method to simplify code generation via python scripts.

    http://www.scons.org/wiki/UsingCodeGenerators
    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html
    """

    # We're generating code using Python scripts, so we have to be
    # careful with our scons elements.  This entry represents
    # the generator file *in the source directory*.
    script_src = env.File(script).srcnode()

    # This command creates generated code *in the build directory*.
    command = command.replace('$SCRIPT', script_src.path)
    action = SCons.Action.Action(command, "$CODEGENCOMSTR")
    code = env.Command(target, source, action)

    # Explicitly mark that the generated code depends on the generator,
    # and on implicitly imported python modules
    path = (script_src.get_dir(),) if scons_version < (2, 5, 0) else lambda x: script_src
    deps = [script_src]
    deps += script_src.get_implicit_deps(env, python_scanner, path)
    env.Depends(code, deps)

    # Running the Python script causes .pyc files to be generated in the
    # source directory.  When we clean up, they should go too. So add side
    # effects for .pyc files
    for dep in deps:
        pyc = env.File(str(dep) + 'c')
        env.SideEffect(pyc, code)

    return code


def createCodeGenerateMethod(env):
    env.Append(SCANNERS = python_scanner)
    env.AddMethod(code_generate, 'CodeGenerate')


def _pkg_check_modules(env, name, modules):
    '''Simple wrapper for pkg-config.'''

    env['HAVE_' + name] = False

    # For backwards compatability
    env[name.lower()] = False

    if env['platform'] == 'windows':
        return

    if not env.Detect('pkg-config'):
        return

    if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0:
        return

    # Strip version expressions from modules
    modules = [module.split(' ', 1)[0] for module in modules]

    # Other flags may affect the compilation of unrelated targets, so store
    # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
    try:
        flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules))
    except OSError:
        return
    prefix = name + '_'
    for flag_name, flag_value in flags.items():
        assert '_' not in flag_name
        env[prefix + flag_name] = flag_value

    env['HAVE_' + name] = True

def pkg_check_modules(env, name, modules):

    sys.stdout.write('Checking for %s (%s)...' % (name, ' '.join(modules)))
    _pkg_check_modules(env, name, modules)
    result = env['HAVE_' + name]
    sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])

    # XXX: For backwards compatability
    env[name.lower()] = result


def pkg_use_modules(env, names):
    '''Search for all environment flags that match NAME_FOO and append them to
    the FOO environment variable.'''

    names = env.Flatten(names)

    for name in names:
        prefix = name + '_'

        if not 'HAVE_' + name in env:
            raise Exception('Attempt to use unknown module %s' % name)

        if not env['HAVE_' + name]:
            raise Exception('Attempt to use unavailable module %s' % name)

        flags = {}
        for flag_name, flag_value in env.Dictionary().items():
            if flag_name.startswith(prefix):
                flag_name = flag_name[len(prefix):]
                if '_' not in flag_name:
                    flags[flag_name] = flag_value
        if flags:
            env.MergeFlags(flags)


def createPkgConfigMethods(env):
    env.AddMethod(pkg_check_modules, 'PkgCheckModules')
    env.AddMethod(pkg_use_modules, 'PkgUseModules')


def parse_source_list(env, filename, names=None):
    # parse the source list file
    parser = source_list.SourceListParser()
    src = env.File(filename).srcnode()

    cur_srcdir = env.Dir('.').srcnode().abspath
    top_srcdir = env.Dir('#').abspath
    top_builddir = os.path.join(top_srcdir, env['build_dir'])

    # Normalize everything to / slashes
    cur_srcdir = cur_srcdir.replace('\\', '/')
    top_srcdir = top_srcdir.replace('\\', '/')
    top_builddir = top_builddir.replace('\\', '/')

    # Populate the symbol table of the Makefile parser.
    parser.add_symbol('top_srcdir', top_srcdir)
    parser.add_symbol('top_builddir', top_builddir)

    sym_table = parser.parse(src.abspath)

    if names:
        if isinstance(names, basestring):
            names = [names]

        symbols = names
    else:
        symbols = list(sym_table.keys())

    # convert the symbol table to source lists
    src_lists = {}
    for sym in symbols:
        val = sym_table[sym]
        srcs = []
        for f in val.split():
            if f:
                # Process source paths
                if f.startswith(top_builddir + '/src'):
                    # Automake puts build output on a `src` subdirectory, but
                    # SCons does not, so strip it here.
                    f = top_builddir + f[len(top_builddir + '/src'):]
                if f.startswith(cur_srcdir + '/'):
                    # Prefer relative source paths, as absolute files tend to
                    # cause duplicate actions.
                    f = f[len(cur_srcdir + '/'):]
                # do not include any headers
                if f.endswith(tuple(['.h','.hpp','.inl'])):
                    continue
                srcs.append(f)

        src_lists[sym] = srcs

    # if names are given, concatenate the lists
    if names:
        srcs = []
        for name in names:
            srcs.extend(src_lists[name])

        return srcs
    else:
        return src_lists

def createParseSourceListMethod(env):
    env.AddMethod(parse_source_list, 'ParseSourceList')


def generate(env):
    """Common environment generation code"""

    verbose = env.get('verbose', False) or not env.get('quiet', True)
    if not verbose:
        quietCommandLines(env)

    # Custom builders and methods
    createConvenienceLibBuilder(env)
    createCodeGenerateMethod(env)
    createPkgConfigMethods(env)
    createParseSourceListMethod(env)

    # for debugging
    #print env.Dump()


def exists(env):
    return 1
