# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2022,  Regents of the University of California,
                          Arizona Board of Regents,
                          Colorado State University,
                          University Pierre & Marie Curie, Sorbonne University,
                          Washington University in St. Louis,
                          Beijing Institute of Technology,
                          The University of Memphis.

This file is part of NFD (Named Data Networking Forwarding Daemon).
See AUTHORS.md for complete list of NFD authors and contributors.

NFD is free software: you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.

NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
"""

from waflib import Context, Utils

top = '../'

def build(bld):
    # Single object tools:
    # tools/foo.cpp is a self-contained tool with a main() function
    # and is built as build/bin/foo. These tools cannot be unit-tested.
    for tool in bld.path.ant_glob('*.cpp'):
        name = tool.change_ext('').path_from(bld.path.get_bld())
        bld.program(name=name,
                    target=top + 'bin/%s' % name,
                    source=[tool],
                    use='core-objects')

    # Sub-directory tools:
    # tools/foo/**/*.cpp are compiled and linked into build/bin/foo.
    # tools/foo/main.cpp must exist and must contain the main() function.
    # All other objects are collected into 'tools-objects' and can be unit-tested.
    testableObjects = []
    for subdir in bld.path.ant_glob('*', dir=True, src=False):
        name = subdir.path_from(bld.path)
        subWscript = subdir.find_node('wscript')
        if subWscript:
            # if the subdir has a wscript, delegate to it
            bld.recurse(name)
            continue

        mainFile = subdir.find_node('main.cpp')
        if mainFile is None:
            # not a C++ tool, skip the subdir
            continue

        srcFiles = subdir.ant_glob('**/*.cpp', excl=['main.cpp'])
        srcObjects = ''
        if srcFiles:
            srcObjects = 'tools-%s-objects' % name
            bld.objects(target=srcObjects,
                        source=srcFiles,
                        features='pch',
                        headers=subdir.find_node(name + '-pch.hpp'),
                        use='core-objects LIBRESOLV',
                        includes=name)
            testableObjects.append(srcObjects)

        bld.program(name=name,
                    target=top + 'bin/%s' % name,
                    source=[mainFile],
                    use='core-objects ' + srcObjects,
                    includes=name)

    bld.objects(target='tools-objects',
                source=[],
                export_includes='.',
                use=testableObjects)

    # Scripts
    for script in bld.path.ant_glob(['*.sh', '*.py']):
        name = script.change_ext('').path_from(bld.path.get_bld())
        bld(features='subst',
            name=name,
            target=top + 'bin/%s' % name,
            source=[script],
            install_path='${BINDIR}',
            chmod=Utils.O755,
            VERSION=Context.g_module.VERSION)

    bld.install_files('${DATAROOTDIR}/ndn',
                      bld.path.ant_glob('nfd-status-http-server-files/*'))
