#!/usr/bin/env Rscript

script_arg <- commandArgs(trailingOnly = FALSE)[grep("^--file=", commandArgs(trailingOnly = FALSE))][1]
script_path <- normalizePath(sub("^--file=", "", script_arg), winslash = "/", mustWork = TRUE)
root_dir <- normalizePath(file.path(dirname(script_path), "..", ".."), winslash = "/", mustWork = TRUE)
src_dir <- file.path(root_dir, "src")
makevars_path <- file.path(src_dir, "Makevars")
nomad_root <- "nomad4_src"

wrap_make_var <- function(name, values, indent = "  ") {
  if (!length(values)) {
    return(sprintf("%s =", name))
  }

  lines <- character()
  current <- sprintf("%s = %s", name, values[[1]])

  if (length(values) == 1L) {
    return(current)
  }

  current <- paste0(current, " \\")
  lines <- c(lines, current)

  for (i in 2:length(values)) {
    value <- values[[i]]
    if (i < length(values)) {
      lines <- c(lines, paste0(indent, value, " \\"))
    } else {
      lines <- c(lines, paste0(indent, value))
    }
  }

  lines
}

rel_from_src <- function(paths) {
  sub(paste0("^", src_dir, "/"), "", paths)
}

nomad_cpp <- sort(rel_from_src(list.files(
  file.path(src_dir, nomad_root, "src"),
  pattern = "\\.cpp$",
  recursive = TRUE,
  full.names = TRUE
)))

nomad_cpp <- nomad_cpp[
  !grepl("^nomad4_src/src/Algos/COOPMads/", nomad_cpp) &
    !grepl("^nomad4_src/src/Algos/PSDMads/", nomad_cpp) &
    nomad_cpp != "nomad4_src/src/Attribute/WriteAttributeDefinitionFile.cpp" &
    nomad_cpp != "nomad4_src/src/Algos/PSDMads/PSDMadsMegaIteration_prev.cpp"
]

sgtelib_cpp <- sort(rel_from_src(list.files(
  file.path(src_dir, nomad_root, "ext", "sgtelib", "src"),
  pattern = "\\.cpp$",
  recursive = FALSE,
  full.names = TRUE
)))

sgtelib_cpp <- sgtelib_cpp[!sgtelib_cpp %in% c(
  "nomad4_src/ext/sgtelib/src/sgtelib.cpp",
  "nomad4_src/ext/sgtelib/src/sgtelib_predict.cpp",
  "nomad4_src/ext/sgtelib/src/Tests.cpp"
)]

cinterface_cpp <- "nomad4_src/interfaces/CInterface/NomadStdCInterface.cpp"

nomad_objects <- sub("\\.cpp$", ".o", c(nomad_cpp, sgtelib_cpp, cinterface_cpp))

include_dirs <- sort(rel_from_src(list.dirs(
  file.path(src_dir, nomad_root, "src"),
  recursive = TRUE,
  full.names = TRUE
)))
include_flags <- c(
  paste0("-I./", include_dirs),
  "-I./nomad4_src/interfaces/CInterface",
  "-I./nomad4_src/ext/sgtelib/src"
)

base_objects <- c(
  "RuniqueCombs.o",
  "bspline.o",
  "gsl_bspline.o",
  "snomadr.o",
  "crs_init.o",
  "mgcv.o",
  "hat_diag.o"
)

contents <- c(
  "# Generated by tools/nomad/generate_makevars_manifest.R",
  "# Regenerate this file after updating vendored NOMAD/SGTELIB sources.",
  "",
  "NOMAD4_ROOT = ./nomad4_src",
  "",
  "# Static NOMAD 4 source manifest (portable Makevars; no GNU make discovery).",
  wrap_make_var("NOMAD4_SRC_CPP", nomad_cpp),
  "",
  wrap_make_var("NOMAD4_SGTELIB_CPP", sgtelib_cpp),
  "",
  "NOMAD4_CINT_CPP = $(NOMAD4_ROOT)/interfaces/CInterface/NomadStdCInterface.cpp",
  "",
  wrap_make_var("NOMAD4_OBJECTS", nomad_objects),
  "",
  wrap_make_var("NOMAD4_INCLUDE_FLAGS", include_flags),
  "",
  wrap_make_var("OBJECTS", c(base_objects, "$(NOMAD4_OBJECTS)")),
  "",
  "PKG_CXXFLAGS = $(NOMAD4_INCLUDE_FLAGS) -DUSE_SGTELIB -DNOMAD_STATIC_BUILD",
  ""
)

writeLines(contents, makevars_path, useBytes = TRUE)

cat(sprintf("Wrote %s\n", makevars_path))
cat(sprintf("NOMAD sources: %d\n", length(nomad_cpp)))
cat(sprintf("SGTELIB sources: %d\n", length(sgtelib_cpp)))
cat(sprintf("Include dirs: %d\n", length(include_dirs)))
