#!/bin/sh
#
# configure for the Uno R package.
#
# Builds the Uno static library (and, in later milestones, its HiGHS QP/LP
# subproblem solver) from source via CMake, then generates src/Makevars.

R_UNO_PKG_HOME=`pwd`

: ${R_HOME=`R RHOME`}
if test -z "${R_HOME}"; then
    echo "'R_HOME' could not be found!"
    exit 1
fi

# Locate the MUMPS C-API headers shipped by the 'rmumps' package. build_uno.sh
# compiles Uno's MUMPSSolver.cpp against these (header-only); we link NO MUMPS
# library -- the single dmumps_c entry point is resolved at runtime from rmumps
# via R_FindSymbol (see src/dmumps_shim.c). This enables the interior-point
# (e.g. "ipopt") preset. Skip with R_UNO_NO_MUMPS=1 (filtersqp/HiGHS only).
if test -z "${R_UNO_NO_MUMPS}"; then
    RMUMPS_INC=`"${R_HOME}/bin/Rscript" -e 'cat(system.file("include", package="rmumps"))'`
    if test -z "${RMUMPS_INC}" || test ! -f "${RMUMPS_INC}/dmumps_c.h"; then
        echo "rmumps headers not found (looked in '${RMUMPS_INC}')."
        echo "Install 'rmumps' (>= 5.2.1-41), or set R_UNO_NO_MUMPS=1 to build without MUMPS."
        exit 1
    fi
    export MUMPS_R_INCLUDE_DIRS="${RMUMPS_INC}"
    echo "MUMPS headers (rmumps): ${MUMPS_R_INCLUDE_DIRS}"
fi

# Build the HiGHS QP/LP subproblem solver (static libhighs.a) from source.
# This enables Uno's SQP presets (e.g. filtersqp). Skip with R_UNO_NO_HIGHS=1.
HIGHS_PKG_LIBS=""
HIGHS_CPPFLAGS=""
if test -z "${R_UNO_NO_HIGHS}"; then
    bash inst/build_highs.sh || { echo "HiGHS build failed!"; exit 1; }
    cd "${R_UNO_PKG_HOME}"
    R_HIGHS_LIB_DIR=${R_UNO_PKG_HOME}/src/highslib
    # Tell build_uno.sh to compile Uno with HAS_HIGHS + the HiGHSSolver sources.
    export HIGHS_LIB="${R_HIGHS_LIB_DIR}/lib/libhighs.a"
    HIGHS_PKG_LIBS="-L${R_HIGHS_LIB_DIR}/lib -lhighs"
    HIGHS_CPPFLAGS="-I${R_HIGHS_LIB_DIR}/include -I${R_HIGHS_LIB_DIR}/include/highs"
fi

# Build the Uno static library (src/unolib/{lib,include}).
bash inst/build_uno.sh || { echo "Uno build failed!"; exit 1; }
cd "${R_UNO_PKG_HOME}"

# Now that the static libraries (src/highslib, src/unolib) are built, drop the
# bundled HiGHS and Uno SOURCE trees on a TARBALL install to shrink the
# installed package -- the binding links the built libs+headers, not the
# sources.  Mirrors the scip R package's configure, which keys off pre-built
# vignettes in inst/doc/ as the tarball-install marker.  Extra guard vs. scip:
# inst/HiGHS and inst/uno are git SUBMODULES, so we only remove them when they
# are NOT a submodule working tree (a tarball has no nested .git), to never
# delete a developer's checked-out source during an in-place `R CMD INSTALL .`.
# The bundled source lives under inst/ (not src/) so that R CMD check's src-only
# pragma/line-ending scans never see the vendored third-party files; removing it
# here keeps it out of the *installed* package (R copies inst/ after configure).
if test -d inst/doc; then
    test -e inst/HiGHS/.git || rm -rf inst/HiGHS
    test -e inst/uno/.git   || rm -rf inst/uno
fi

# Remove the intermediate CMake build trees: the libraries are installed under
# src/highslib and src/unolib, so the build dirs are dead weight, and their
# CMake-generated Makefiles carry CRLF line endings on Windows -> R CMD check
# "line endings in Makefiles" WARNING.
rm -rf highs_build uno_build

# Normalize the installed HiGHS/Uno headers so R CMD check stays quiet:
#   * strip CRLF -> LF  (Windows CMake emits CRLF -> "line endings in sources" NOTE)
#   * ensure a trailing newline  (some upstream headers ship without one ->
#     "sources/headers not terminated with a newline" NOTE)
# The trailing-newline test: $(tail -c1 f) strips a final LF in command
# substitution, so it is non-empty exactly when the last byte is NOT a newline.
# Both passes are no-ops on already-clean files.
for incdir in src/highslib/include src/unolib/include; do
    test -d "${incdir}" || continue
    find "${incdir}" -type f -print | while read f; do
        tr -d '\r' < "$f" > "$f.tmp"
        if test -s "$f.tmp" && test -n "$(tail -c1 "$f.tmp")"; then
            printf '\n' >> "$f.tmp"
        fi
        mv "$f.tmp" "$f"
    done
done

R_UNO_LIB_DIR=${R_UNO_PKG_HOME}/src/unolib

# Link flags: the Uno static archive resolves its BLAS/LAPACK/Fortran-runtime
# externals (and HiGHS, if built) at the final package .so link.
RUNO_PKG_LIBS="-L${R_UNO_LIB_DIR}/lib -luno ${HIGHS_PKG_LIBS}"

sed -e "s|@RUNO_LIB_DIR@|${R_UNO_LIB_DIR}|g" \
    -e "s|@RUNO_PKG_LIBS@|${RUNO_PKG_LIBS}|g" \
    src/Makevars.in > src/Makevars

if [ -z "$(ls ${R_UNO_LIB_DIR} 2>/dev/null | grep 'include')" ]; then
    echo "Uno headers could not be found!"
    exit 1
fi
