from waflib import Logs, Errors
import os

CYTHON_PRECOMPILED_VERSION = (0,15,1)

def copy_cython(task):
    """Copy generated cython file from build tree to source tree.
    Also strip the timestamp from the first line comment.
    """
    import re
    node = task.inputs[0]
    orig_file = node.get_bld().abspath()
    copy_file = node.get_src().abspath()
    orig = None
    copy = None
    try:
        orig = open(orig_file, 'rb')
        copy = open(copy_file, 'wb')
        i = 0
        comment = None
        for l in orig:
            sl = l.decode('utf-8')
            if i != 0:
                sl = sl.strip()
            if i == 0:
                l = re.sub(' on .* \\*/', ' */', sl).encode('utf-8')
            elif comment:
                end_c = sl.find('*/')
                if end_c < 0:
                    comment += l
                else:
                    if end_c != len(sl) - 2:
                        copy.write(comment + l)
                    comment = None
                l = None
            elif sl[0:2] == '/*' and sl.find('*/') < 0:
                comment = l
                l = None
            if l:
                copy.write(l)
            i += 1
    finally:
        if orig:
            orig.close()
        if copy:
            copy.close()


def build_precompiled(bld):
    for t in ['xmmsvalue', 'xmmsapi']:
        bld(features = 'c cshlib pyext',
            source = t+'.c',
            target = t,
            use = 'xmmsclient',
            includes = '../../../.. ../../../include ../../../includepriv',
            install_path = '${xmmsclient_PYTHONARCHDIR}',
            mac_bundle = bld.env.mac_bundle_enabled
            )

def build_cython(bld):
    for t in ['xmmsvalue', 'xmmsapi']:
        bld(features = 'c cshlib pyext',
            name = 'gen_'+t,
            source = t+'.pyx',
            target = t,
            use = 'xmmsclient',
            includes = '../../../.. ../../../include ../../../includepriv',
            install_path = '${xmmsclient_PYTHONARCHDIR}',
            mac_bundle = bld.env.mac_bundle_enabled,
            cython_includes = ['cython_include']
            )

        # Copy generated file in source tree.
        if bld.options.cython_copy == 'iknowwhatiamdoing':
            bld(rule = copy_cython,
                source = t+'.c',
                after = 'gen_'+t)

def build(bld):
    if bld.env.xmmspython_USE_PRECOMPILED:
        build_precompiled(bld)
    else:
        build_cython(bld)

    pure_files = bld.path.ant_glob('xmmsclient/*.py')
    sample_files = bld.path.ant_glob('xmmsclient/samples/*.py')

    bld.install_files('${xmmsclient_PYTHONARCHDIR}', pure_files)
    bld.install_files('${xmmsclient_PYTHONARCHDIR}/samples', sample_files)
    # TODO: Distribute .pxd files

def configure(conf):
    conf.load('python')
    if not conf.env.PYTHON:
        conf.fatal("python not found")

    conf.check_python_version()
    conf.check_python_headers()

    conf.env.xmmsclient_PYTHONARCHDIR = os.path.join(conf.env.PYTHONARCHDIR, 'xmmsclient')

    prefix = os.path.commonprefix([conf.env.PYTHONARCHDIR, conf.env.PREFIX])
    if prefix != conf.env.PREFIX:
        Logs.warn("Default python libdir is not under PREFIX. Specify path "
                  "manually using the PYTHONARCHDIR environment variable if you "
                  "don't want the python bindings to be installed to %s"
                  % conf.env.PYTHONARCHDIR)

    has_precompiled = len(conf.path.ant_glob('xmms*.c')) > 0
    conf.env.xmmspython_USE_PRECOMPILED = True
    if not getattr(conf.options, 'no_cython', False):
        try:
            conf.load('cython cython_extra', tooldir='waftools')
            conf.check_cython_version(minver = '0.13')
            conf.env.append_unique('CYTHONFLAGS', '-Xembedsignature=True')
        except Errors.ConfigurationError:
            if not has_precompiled:
                raise
        else:
            conf.env.xmmspython_USE_PRECOMPILED = not conf.env.CYTHON
            if not has_precompiled and not conf.env.CYTHON:
                conf.fatal('Python bindings require Cython')

    if not conf.env.xmmspython_USE_PRECOMPILED and has_precompiled and \
            conf.env.CYTHON_VERSION < CYTHON_PRECOMPILED_VERSION:
        Logs.warn("Your version of cython is older than the one used to "
                  "generate precompiled files. If you did not edit cython "
                  "files, you should consider reconfiguring with --no-cython")

def options(opt):
    opt.load('python')
    opt.load('cython', tooldir='waftools')
    if opt.path.ant_glob('xmms*.c'):
        opt.add_option('--no-cython', action="store_true",
                dest="no_cython", default=False,
                help="Use precompiled cython files even if cython is installed on "
                     "the system.")
    opt.add_option('--cython-copy-files', type="string",
            dest="cython_copy", default="",
            help="Copy generated files in the source tree. "
                 "Works only with the 'build' command. "
                 "Must have the value 'iknowwhatiamdoing' to work. "
                 "This option is intended for releases only.")
