#[[
CMake build script for ACM Collected Algorithms: DCUHRE and DQUAD
Copyright (C) 2025  Tim Kaune

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

This program 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program.  If not, see
<https://www.gnu.org/licenses/>.
]]

find_program(TAIL_EXE tail REQUIRED)
find_program(HEAD_EXE head REQUIRED)

FetchContent_Declare(
    netlib_DQUAD
    URL "https://calgo.acm.org/691.zip"
    URL_HASH SHA256=8f6fdcab17b0386b1ef79a2a4018c80075a0fb6c609d7d60d4be747e98f7485c
)
FetchContent_MakeAvailable(netlib_DQUAD)
FetchContent_GetProperties(
    netlib_DQUAD
    SOURCE_DIR DQUAD_FORTRAN_DIR
)

set(
    DQUAD_LIB_SINGLE_FILENAMES
    "saux"
    "squad"
)
set(
    DQUAD_TEST_SINGLE_FILENAMES
    "stest"
    CACHE
    INTERNAL
    ""
)
set(
    DQUAD_LIB_DOUBLE_FILENAMES
    "daux"
    "dquad"
)
set(
    DQUAD_TEST_DOUBLE_FILENAMES
    "dtest"
    CACHE
    INTERNAL
    ""
)
set(
    DQUAD_FORTRAN_FILENAMES
    ${DQUAD_LIB_SINGLE_FILENAMES}
    ${DQUAD_TEST_SINGLE_FILENAMES}
    ${DQUAD_LIB_DOUBLE_FILENAMES}
    ${DQUAD_TEST_DOUBLE_FILENAMES}
)
list(TRANSFORM DQUAD_FORTRAN_FILENAMES APPEND ".f")
set(DQUAD_FORTRAN_SOURCES ${DQUAD_FORTRAN_FILENAMES})
list(TRANSFORM DQUAD_FORTRAN_SOURCES PREPEND "${DQUAD_FORTRAN_DIR}/")
set(DQUAD_BYPRODUCTS  "LICENSE" "README")
list(TRANSFORM DQUAD_BYPRODUCTS PREPEND "${DQUAD_FORTRAN_DIR}/")

add_custom_command(
    OUTPUT ${DQUAD_FORTRAN_SOURCES}
    COMMAND ${HEAD_EXE} -n 50 "Original/691.txt" > "README"
    COMMAND ${HEAD_EXE} -n 87 "Original/691.txt" | ${TAIL_EXE} -n +52 > "LICENSE"
    COMMAND ${HEAD_EXE} -n 808 "Original/691.txt" | ${TAIL_EXE} -n +88 > "daux.f"
    COMMAND ${HEAD_EXE} -n 2338 "Original/691.txt" | ${TAIL_EXE} -n +809 > "dquad.f"
    COMMAND ${HEAD_EXE} -n 2403 "Original/691.txt" | ${TAIL_EXE} -n +2339 > "dtest.f"
    COMMAND ${HEAD_EXE} -n 3096 "Original/691.txt" | ${TAIL_EXE} -n +2440 > "saux.f"
    COMMAND ${HEAD_EXE} -n 4626 "Original/691.txt" | ${TAIL_EXE} -n +3097 > "squad.f"
    COMMAND ${TAIL_EXE} -n +4627 "Original/691.txt" > "stest.f"
    DEPENDS "${DQUAD_FORTRAN_DIR}/Original/691.txt"
    BYPRODUCTS ${DQUAD_BYPRODUCTS}
    WORKING_DIRECTORY "${DQUAD_FORTRAN_DIR}"
    COMMENT "Extracting archive"
    VERBATIM
)

set(DQUAD_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")

set(
    DQUAD_SOURCES
    ${DQUAD_LIB_SINGLE_FILENAMES}
    ${DQUAD_TEST_SINGLE_FILENAMES}
    ${DQUAD_LIB_DOUBLE_FILENAMES}
    ${DQUAD_TEST_DOUBLE_FILENAMES}
)
list(TRANSFORM DQUAD_SOURCES APPEND ".c")
list(TRANSFORM DQUAD_SOURCES PREPEND "${DQUAD_SOURCE_DIR}/")

add_custom_command(
    OUTPUT ${DQUAD_SOURCES}
    COMMAND Netlib::f2c -a -d${DQUAD_SOURCE_DIR} ${DQUAD_FORTRAN_FILENAMES}
    DEPENDS ${DQUAD_FORTRAN_SOURCES}
    WORKING_DIRECTORY "${DQUAD_FORTRAN_DIR}"
    COMMENT "Converting DQUAD from Fortran to C"
    VERBATIM
)

add_library(DQUAD)
add_library(Netlib::DQUAD ALIAS DQUAD)

target_compile_features(DQUAD PRIVATE c_std_90)
target_compile_options(DQUAD PRIVATE -w)
target_link_libraries(DQUAD PUBLIC Netlib::libf2c)

set_target_properties(
    DQUAD PROPERTIES
    VERSION ${CalgoIntegrators_VERSION}
    SOVERSION ${CalgoIntegrators_VERSION_MAJOR}
    RELEASE_POSTFIX "${CALGO_INTEGRATORS_RELEASE_POSTFIX}"
    DEBUG_POSTFIX "${CALGO_INTEGRATORS_DEBUG_POSTFIX}"
    C_STANDARD 90
    INSTALL_RPATH_USE_LINK_PATH TRUE
)

set(
    DQUAD_LIB_SOURCES
    ${DQUAD_LIB_SINGLE_FILENAMES}
    ${DQUAD_LIB_DOUBLE_FILENAMES}
)
list(TRANSFORM DQUAD_LIB_SOURCES APPEND ".c")
list(TRANSFORM DQUAD_LIB_SOURCES PREPEND "${DQUAD_SOURCE_DIR}/")

target_sources(DQUAD PRIVATE ${DQUAD_LIB_SOURCES})
target_sources(DQUAD PUBLIC
    FILE_SET HEADERS
    BASE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
    FILES "${CMAKE_CURRENT_SOURCE_DIR}/dquad.h"
)

target_include_directories(DQUAD PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)
