from waflib import Context, Logs, Options, Task
from waflib.Configure import conf

APPNAME = "fileseq"

top = '.'
out = 'build'


def options(opt):
    opt.load('compiler_cxx')
    opt.add_option('--force-pcre', action='store_true', default=False, dest='force_pcre',
                   help="Build against libpcre regardless of availability of C++11 <regex>")


def configure(ctx):
    ctx.load('compiler_cxx')
    ctx.env.append_unique('CXXFLAGS', ['-fPIC', '-std=c++11'])
    ctx.check_cxx_regex()


def build(bld):
    objs = bld.objects(
        target='fileseq_obj',
        source=bld.path.ant_glob(['*.cpp', 'ranges/*.cpp', 'private/*.cpp']),
        includes=['.', 'ranges', 'private'],
    )

    opts = {}
    if bld.get_define("HAVE_REGEX") != "1":
        opts['use'] = "PCRE"
        opts['stlib'] = "pcrecpp"

    bld.shlib(
        name="fileseq_shared",
        source=[],
        target=APPNAME,
        use=[objs.target],
        features='cxx cxxshlib')

    bld.stlib(
        name="fileseq_static",
        source=[],
        target=APPNAME,
        use=[objs.target],
        features='cxx cxxstlib')

    # Install headers
    bld.install_files('${PREFIX}/include/fileseq', bld.path.ant_glob("*.h"))

    # Test
    #
    if _is_test:
        _create_test(bld)


_is_test = False


def test(bld):
    Options.commands = ['build'] + Options.commands

    global _is_test
    _is_test = True


def _create_test(bld):
    use = ["fileseq_static"]
    stlib = []

    if bld.get_define("HAVE_REGEX") != "1":
        use.append('PCRE')
        stlib += ['pcrecpp', 'pcre']

    tsk = bld.program(
        target='TestFileseq',
        source=bld.path.ant_glob([
            'test/main.cc',
            'test/Test*.cc',
            'test/gtest/src/gtest-all.cc']),
        includes=["test", "test/gtest/include", "test/gtest", "."],
        use=use,
        lib=['pthread'],
        stlib=stlib,
        cxxflags=["-Wno-undef", "-g", "-ggdb"],
        defines=["FILESEQ_TEST_DIR=%s" % bld.path.parent.abspath()],
    )

    bld(
        rule="cd %s && ./${SRC}" % bld.variant_dir,
        source=tsk.target,
        use="test_fileseq",
        always=True,
    )


REGEX_CPP_TEST = '''
#include <iostream>
#include <regex>
using namespace std;
int main() {
    smatch match;
    if (regex_match(string("_OK_"), match, regex("_(OK)_"))) {
        cout << (match[1].str() == "OK" ? "1" : "0");
    }
    return 0;
}
'''


@conf
def check_cxx_regex(ctx):
    if ctx.options.force_pcre:
        have_regex = "0"
    else:
        have_regex = ctx.check_cxx(
            execute=True,
            define_ret=True,
            msg="Checking for <regex> support",
            okmsg="Done",
            cxxflags=['-std=c++11'],
            fragment=REGEX_CPP_TEST,
            mandatory=False,
        )

    if have_regex and have_regex.strip() == "1":
        ctx.define("HAVE_REGEX", 1, comment="C++11 <regex> is supported")
    else:
        ctx.check_cxx(
            header_name='pcrecpp.h',
            stlib='pcrecpp',
            use='PCRE',
            msg='Checking for static library pcrecpp')
