#' @title Helpers to Create Manual Pages
#'
#' @description
#' `rd_info()` is an internal generic to generate Rd or markdown code to be used in manual pages.
#' `rd_format_string()` and `rd_format_range()` are string functions to assist generating
#' proper Rd code.
#'
#' @param obj (`any`)\cr
#'   Object of the respective class.
#' @param ... (`any)`)\cr
#'   Additional arguments.
#'
#' @return `character()`, possibly with markdown code.
#' @keywords Internal
#' @export
rd_info = function(obj, ...) {
  UseMethod("rd_info")
}

#' @rdname rd_info
#' @param lower (`numeric(1)`)\cr
#'   Lower bound.
#' @param upper (`numeric(1)`)\cr
#'   Upper bound.
#' @export
rd_format_range = function(lower, upper) {
  if (is.na(lower) || is.na(upper)) {
    return("-")
  }

  str = sprintf(
    "%s%s, %s%s",
    if (is.finite(lower)) "[" else "(",
    if (is.finite(lower)) c(lower, lower) else c("-\\infty", "-Inf"),
    if (is.finite(upper)) c(upper, upper) else c("\\infty", "Inf"),
    if (is.finite(upper)) "]" else ")"
  )
  paste0("\\eqn{", str[1L], "}{", str[2L], "}")
}

#' @rdname rd_info
#' @inheritParams str_collapse
#' @export
rd_format_string = function(str, quote = c("\\dQuote{", "}")) {
  if (length(str) == 0L) {
    return("-")
  }
  str_collapse(str, quote = quote)
}


#' @rdname rd_info
#' @param packages (`character()`)\cr
#'   Vector of package names.
#' @export
rd_format_packages = function(packages) {
  if (length(packages) == 0L) {
    return("-")
  }
  base_pkgs = c(
    "base",
    "compiler",
    "datasets",
    "graphics",
    "grDevices",
    "grid",
    "methods",
    "parallel",
    "splines",
    "stats",
    "stats4",
    "tcltk",
    "tools",
    "translations",
    "utils"
  )
  link = packages %nin% base_pkgs
  str_collapse(sprintf("%s%s%s", fifelse(link, "\\CRANpkg{", "'"), packages, fifelse(link, "}", "'")))
}
