import os.path

Import('env', 'lib_env', 'gen_env', 'tool_env', 'test_env', 'pulse_env')

env.Append(CPPPATH=['#src/modules'])

for targetdir in env.GlobRecursive('modules', 'target_*'):
    if targetdir.name in env['ROC_TARGETS']:
        env.Append(CPPPATH=['#src/%s' % targetdir])

for module in env['ROC_MODULES']:
    moduledir = 'modules/' + module

    cenv = env.Clone()
    cenv.MergeVars(tool_env)
    cenv.Append(CPPDEFINES=('ROC_MODULE', module))

    genv = gen_env.Clone()
    genv.MergeVars(cenv)

    sources = []
    objects = []

    sources += env.GlobFiles('%s/*.cpp' % moduledir)
    for rs in env.GlobFiles('%s/*.rl' % moduledir):
        objects += genv.Ragel(rs)

    for targetdir in env.GlobRecursive(moduledir, 'target_*'):
        if targetdir.name in env['ROC_TARGETS']:
            sources += env.GlobRecursive(targetdir, '*.cpp')
            for rs in env.GlobRecursive(targetdir, '*.rl'):
                objects += genv.Ragel(rs)

    if not sources and not objects:
        continue

    lib = cenv.StaticLibrary(module, sources+objects)
    env.Alias(module, [lib], env.Action(''))
    env.AlwaysBuild(module)

    env.Prepend(LIBS=[lib])

libroc = None

if not GetOption('disable_lib'):
    cenv = env.Clone()
    cenv.MergeVars(lib_env)
    cenv.Append(CPPDEFINES=('ROC_MODULE', 'roc_lib'))
    cenv.Append(CPPPATH=['lib/include'])

    sources = env.GlobFiles('lib/src/*.cpp')

    libroc = cenv.SharedLibrary(
        'roc_unstripped', sources, SHLIBSUFFIX=lib_env['SHLIBSUFFIX'])

    env.Depends(libroc, '#src/lib/roc.version')

    libroc = cenv.MaybeStripLibrary(libroc[0].name.replace('_unstripped', ''),
        libroc, is_debug=GetOption('enable_debug'))

    target = env.Install(env['ROC_BINDIR'], libroc)
    symlinks = env.SymlinkLibrary(target[0])

    env.Alias('libroc', [target] + symlinks, env.Action(''))
    env.AlwaysBuild('libroc')

    env.AddDistFile(env['ROC_SYSTEM_INCDIR'], '#src/lib/include/roc')
    env.AddDistFile(env['ROC_SYSTEM_LIBDIR'], target)

    env.AddDistAction(env.FixupLibrary(
        os.path.join(env['ROC_SYSTEM_LIBDIR'], target[0].name)))

    for s in symlinks:
        env.AddDistFile(env['ROC_SYSTEM_LIBDIR'], s)

if not GetOption('disable_examples'):
    cenv = env.Clone()
    cenv.MergeVars(tool_env)
    cenv.MergeVars(test_env)
    cenv.Append(CPPPATH=['lib/include'])
    cenv.Append(LIBS=[libroc])

    targets = []

    for source in env.GlobFiles('lib/example/*.c'):
        example = os.path.splitext(source.name)[0]
        exename = 'roc-example-' + example.replace('_', '-')

        if example.endswith('_sox') and GetOption('disable_sox'):
            continue

        exe = cenv.Program(exename, [source],
                    RPATH=(cenv['RPATH'] if 'RPATH' in cenv.Dictionary() else None))

        env.Depends(exe, libroc)
        targets.append(env.Install(env['ROC_BINDIR'], exe))

    env.Alias('examples', targets, env.Action(''))
    env.AlwaysBuild('examples')

if not GetOption('disable_tests'):
    cenv = env.Clone()
    cenv.MergeVars(tool_env)
    cenv.MergeVars(test_env)
    cenv.Append(CPPDEFINES=('ROC_MODULE', 'roc_test'))

    test_main = cenv.Object('tests/test_main.cpp')

    for testname in env['ROC_MODULES'] + ['roc_lib']:
        testdir = 'tests/' + testname

        ccenv = cenv.Clone()
        ccenv.Append(CPPPATH=['#src/%s' % testdir])

        if testname == 'roc_lib':
            ccenv.Append(CPPPATH=['lib/include'])
            ccenv.Prepend(LIBS=[libroc])

        sources = env.GlobFiles('%s/*.cpp' % testdir)
        for targetdir in env.GlobRecursive(testdir, 'target_*'):
            if targetdir.name in env['ROC_TARGETS']:
                ccenv.Append(CPPPATH=['#src/%s' % targetdir])
                sources += env.GlobRecursive(targetdir, '*.cpp')

        if not sources:
            continue

        exename = 'roc-test-' + testname.replace('roc_', '')
        target = env.Install(env['ROC_BINDIR'],
            ccenv.Program(exename, sources + test_main,
                RPATH=(ccenv['RPATH'] if 'RPATH' in ccenv.Dictionary() else None)))

        env.AddTest(testname, '%s/%s' % (env['ROC_BINDIR'], exename))

if not GetOption('disable_tools'):
    for tooldir in env.GlobDirs('tools/*'):
        cenv = env.Clone()
        cenv.MergeVars(tool_env)
        cenv.Append(CPPDEFINES=('ROC_MODULE', tooldir.name))
        cenv.Append(CPPPATH=['tools', '#src/tools/%s' % tooldir.name])

        genv = gen_env.Clone()
        genv.MergeVars(cenv)

        sources = env.GlobFiles('%s/*.cpp' % tooldir)
        objects = []
        for ggo in env.GlobFiles('%s/*.ggo' % tooldir):
            objects += genv.GenGetOpt(ggo, env['ROC_VERSION_STR'])

        exename = tooldir.name.replace('roc_', 'roc-')
        target = env.Install(env['ROC_BINDIR'],
                    cenv.Program(exename, sources+objects))

        env.Alias(exename, [target], env.Action(''))
        env.AlwaysBuild(exename)

        env.AddDistFile(env['ROC_SYSTEM_BINDIR'], target)

if GetOption('enable_pulseaudio_modules'):
    cenv = env.Clone()
    cenv.MergeVars(pulse_env)
    cenv.Append(CPPPATH=['lib/include'])
    cenv.Append(LIBS=[libroc])

    helpers = cenv.Object('pulse/module_helpers.c')
    targets = []

    for source in env.GlobFiles('pulse/module-*.c'):
        module = os.path.splitext(source.name)[0]

        modulelib = cenv.SharedLibrary(module, [source, helpers], LIBPREFIX='')
        env.Depends(modulelib, libroc)

        target = env.Install(env['ROC_BINDIR'], modulelib)
        targets.append(target)

        env.AddDistFile(env['ROC_PULSE_MODULEDIR'], target)

    env.Alias('pulse', targets, env.Action(''))
    env.AlwaysBuild('pulse')
