# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2024,  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/>.
"""

top = '..'

def build(bld):
    # Unit tests
    if bld.env.WITH_TESTS:
        tmpdir = 'UNIT_TESTS_TMPDIR="%s"' % bld.bldnode.make_node('tmp-files')

        # common test objects
        bld.objects(
            target='tests-common',
            features='pch',
            source=bld.path.ant_glob('*.cpp', excl='main.cpp'),
            use='BOOST_TESTS core-objects',
            headers='../core/common.hpp boost-test.hpp',
            defines=[tmpdir])

        for module in ['core', 'daemon', 'tools']:
            # main() for the module
            bld.objects(
                target=f'unit-tests-{module}-main',
                source='main.cpp',
                use='BOOST_TESTS',
                defines=[f'BOOST_TEST_MODULE=NFD {module.capitalize()}'])

            node = bld.path.find_dir(module)
            src = node.ant_glob('**/*.cpp',
                                excl=['face/*ethernet*.cpp',
                                      'face/pcap*.cpp',
                                      'face/unix*.cpp',
                                      'face/websocket*.cpp'])
            if bld.env.HAVE_LIBPCAP:
                src += node.ant_glob('face/*ethernet*.cpp')
                src += node.ant_glob('face/pcap*.cpp')
            if bld.env.HAVE_UNIX_SOCKETS:
                src += node.ant_glob('face/unix*.cpp')
            if bld.env.HAVE_WEBSOCKET:
                src += node.ant_glob('face/websocket*.cpp')

            # unit-tests binary for the module
            bld.program(
                name=f'unit-tests-{module}',
                target=f'{top}/unit-tests-{module}',
                source=src,
                use=f'{module}-objects tests-common unit-tests-{module}-main',
                defines=[tmpdir],
                install_path=None)

    # Other tests (e.g., stress tests and benchmarks that can be enabled even if unit tests are disabled)
    if bld.env.WITH_TESTS or bld.env.WITH_OTHER_TESTS:
        bld.recurse('other')
