# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2023,  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=f'{top}/bin/{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 = f'tools-{name}-objects'
            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=f'{top}/bin/{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=f'{top}/bin/{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/*'))
