"""
@file
@defgroup rtctk RTC Toolkit

@brief RTC Toolkit.

@copyright
  SPDX-FileCopyrightText: 2020-2026 European Southern Observatory (ESO) @n
  SPDX-License-Identifier: LGPL-3.0-only
"""

import os
import re
from wtools.project import declare_project

# Note to maintainers: if adding/removing new/old dependencies to RTC Toolkit, check if the
# pkg-config files need to be adjusted accordingly. For example, when adding new cnf.check_cfg
# calls, these may need to be reflected in some of the pkgconfig/*.pc files by adding entries to
# the "Requires:" field, or similarly adding flags to the "Cflags:" / "Libs:" fields for transient
# dependencies.
# Also remember the .pc files may be affected if the "use=" parameters in the wscript files for
# sub-modules are updated with an external public dependency. Again most likely related to transient
# dependencies.


def configure(cnf):
    # Disable assertion debug checks for release builds.
    if cnf.options.mode == "release":
        if "NDEBUG" not in cnf.env.DEFINES:
            cnf.env.DEFINES.append("NDEBUG")
        if "BOOST_DISABLE_ASSERTS" not in cnf.env.DEFINES:
            cnf.env.DEFINES.append("BOOST_DISABLE_ASSERTS")

    # ______________________________________________________________________________________________
    #
    # Search for header only libraries:
    cnf.check_cxx(
        header_name="nlohmann/json.hpp",
        msg="Checking for <nlohmann/json.hpp> (C++ JSON parsing library)",
    )

    cnf.check_cxx(
        header_name="gsl/span",
        msg="Checking for <gsl/span> (guidelines-support-library)",
    )

    # ______________________________________________________________________________________________
    #
    # Search for pkg-config based dependencies:
    pkgs = (
        "CLI11",
        "log4cplus",
        "cpp-netlib-uri",
        "CCfits",
        "yaml-cpp",
        "backtrace",
        "fmt",
        "benchmark",
        "openblas",
        "libpcap",
        "ppconsul",
        "llnetio",
        "ipcq",
        "numapp",
        "perfc",
        "tbb",
    )
    for pkg in pkgs:
        cnf.check_cfg(package=pkg, uselib_store=pkg, args="--cflags --libs")

    cnf.check_cfg(
        package="cfitsio",
        uselib_store="cfitsio",
        args=["cfitsio >= 4.2.0", "--cflags", "--libs"],
        msg="Checking for 'cfitsio >= 4.2.0'",
    )

    cnf.check_cfg(
        package="taiclock",
        uselib_store="taiclock",
        args=["taiclock >= 0.6.0", "--cflags", "--libs"],
        msg="Checking for 'taiclock >= 0.6.0'",
    )

    if os.getenv("CUDA_PATH") is not None:
        cnf.check_cfg(
            package="cublas-13.3",
            uselib_store="CUBLAS",
            args=["--cflags", "--libs"],
            mandatory=True,
            msg="Checking for 'cublas 13.3'",
        )

    cnf.check_cfg(
        msg="Asking pybind11-config for --includes flags",
        path="pybind11-config",
        package="",
        uselib_store="pybind11",
        args=["--includes"],
    )

    # ______________________________________________________________________________________________
    #
    # Search for Python module dependencies:
    cnf.find_program("pip")
    cnf.check_python_module("click", condition="ver >= num(7, 1, 2)")
    cnf.check_python_module("numpy", condition="ver >= num(1, 20, 0)")
    cnf.check_python_module("astropy", condition="ver >= num(4, 2)")
    cnf.check_python_module("psutil")
    cnf.check_python_module("jinja2")
    cnf.check_python_module("pkg_resources")
    cnf.check_python_module("yaml")
    cnf.check_python_module("IPython")
    cnf.check_python_module("traitlets")
    cnf.check_python_module("setuptools")  # build-time dependency
    cnf.check_python_module("msgsend", condition="ver >= num(0, 7)")
    cnf.check_python_module("taurusmal")
    cnf.check_python_module("tauruscii")
    cnf.check_python_module("elt.cut")
    cnf.check_python_module("elt.pymal")
    cnf.check_python_module("CutWidgets")
    cnf.check_python_module("CiiWidgets")
    cnf.check_python_module("cut.wdglib.bindings")
    cnf.check_python_module("ModStdif")
    cnf.check_python_module("ModIntrospectionif")
    cnf.check_python_module("elt.log")
    cnf.check_python_module("elt.config")
    cnf.check_python_module("elt.error")
    cnf.check_python_module("CiiErrorPyB")
    cnf.check_python_module("elt.configng")
    cnf.check_python_module("elt.oldb")
    cnf.check_python_module("CiiOldbPyB")
    cnf.check_python_module("requests")

    # Qt dependencies for GUIs:
    cnf.check_python_module("PySide6", condition="ver >= num(6, 0, 0)")
    cnf.check_python_module("taurus")
    cnf.check_python_module("taurus_pyqtgraph")

    # ______________________________________________________________________________________________
    #
    # Load various wdep based dependencies:
    pkgs = (
        "rad.cpp.core",
        "rad.cpp.mal",
        "rad.cpp.services",
        "rad.cpp.sm",
        "rad.cpp.utils",
        "rad.scxml4cpp.engine",
        "rad.scxml4cpp.parser",
        "std.if",
        "std.if-cxx",
        "std.introspectionif",
        "std.introspectionif-cxx",
        "metadaq.if",
        "metadaq.if-cxx",
        "client-api.elt-common.cpp.error.client",
        "client-api.cpp.config",
        "client-api.cpp-pybindings.common",
        "config-ng.cpp.config-ng",
        "cii-common-types.cpp.common",
        "cii-services-oldb.cpp.oldb",
        "client-api.elt-common.cpp.log",
        "cii.mal-common.cpp.mal-common",
        "ddt.datatransfer.datatransferlib",
    )
    for pkg in pkgs:
        cnf.check_wdep(wdep_name=pkg, uselib_store=pkg)

    # ______________________________________________________________________________________________
    #
    # Apply environment variable modifications:
    cnf.env.DEFINES_BOOST.append("BOOST_STACKTRACE_USE_BACKTRACE")

    # Make clang-tidy output less verbose. Warnings are still printed as usual but -quiet
    # disables statistics output and configuration hints on how to see all errors.
    cnf.env.append_value("CLANG_TIDY_FLAGS", ["-quiet"])

    if cnf.options.mode == "coverage":
        # Use absolute paths in .gcno coverage files, which may help applications that do not take
        # the compiler working directory into account when resolving source files.
        cnf.env.append_unique("CXXFLAGS", ["-fprofile-abs-path"])

    # ______________________________________________________________________________________________
    #
    # Load additional tooling:
    cnf.load("radgen_tool")

    # Load and enable the gtlogcap tool globally, which captures log4cplus logs during unit tests
    # and prints them on error. Individual modules can disable use of this with attribute
    # `gtlogcap_enable=False`
    cnf.load("gtlogcap")
    cnf.gtlogcap_enable()

    cnf.load("waftool", tooldir=".")


def check_optional():
    import os

    require_list = ""

    if os.getenv("CUDA_PATH") is not None:
        require_list = require_list + " cuda"

    return require_list


declare_project(
    name="rtctk",
    version="6.0.0",
    requires="cxx boost python protoc pyqt gtest fastdds cii sphinx pytest" + check_optional(),
    recurse="componentFramework reusableComponents standaloneTools clients _examples doc pkgconfig",
    boost=dict(libs="program_options chrono filesystem stacktrace_basic thread date_time"),
    qt=dict(version=6),
    cxx=dict(clang_tidy_config=".clang-tidy"),
    doxygen=dict(install_path="${HTMLDIR}/doxygen_doc"),
)
