
utf8 <- function(x) {
  if (is.null(x)) return(x)
  iconv(x, "", "UTF-8")
}

`%||%` <- function(l, r) if (is.null(l)) r else l

cat0 <- function(..., sep = "") {
  cat(..., sep = sep)
}

confirmation <- function(prompt, yes) {
  ans <- readline(paste0(prompt, ": "))
  if (ans != yes) stop("Aborted", call. = FALSE)
}

darwin_version <- function() {
  info <- Sys.info()
  if (info[["sysname"]] != "Darwin") stop("Not macOS")
  package_version(info[["release"]])
}

file_stamp <- function(x) {
  as.character(tools::md5sum(x))
}

str_starts_with <- function(x, p) {
  ncp <- nchar(p)
  substr(x, 1, nchar(p)) == p
}

URLencode <- function(URL) {
  good <- c(LETTERS, letters, 0:9, ".", "_", "~", "-")
  x <- strsplit(URL, "")[[1L]]
  bad <- which(! x %in% good)
  tr <- function(x) {
    paste0("%", toupper(as.character(charToRaw(x))), collapse = "")
  }
  if (length(bad)) x[bad] <- vapply(x[bad], tr, character(1))
  paste(x, collapse = "")
}

get_encoding_opt <- function() {
  chk <- function(x) is.character(x) && length(x) == 1 && !is.na(x)

  enc <- getOption("keyring.encoding_windows")
  if (!is.null(enc) && !chk(enc)) {
    stop("Invalid 'keyring.encoding_windows' option, must be an ",
         "encoding name or 'auto'")
  }

  enc <- enc %||% Sys.getenv("KEYRING_ENCODING_WINDOWS", "auto")

  # Confirm valid encoding. Suggest closest match if not found.
  if (enc != "auto" & !(tolower(enc) %in% tolower(iconvlist()))) {
    icl <- iconvlist()
    closest <- icl[which.min(utils::adist(enc, icl))]
    stop(sprintf(
      "Encoding not found in iconvlist(). Did you mean %s?",
      closest
    ))
  }
  enc
}

is_interactive <- function() {
  opt <- getOption("rlib_interactive")
  if (isTRUE(opt)) {
    TRUE
  } else if (identical(opt, FALSE)) {
      FALSE
  } else if (tolower(getOption("knitr.in.progress", "false")) == "true") {
    FALSE
  } else if (tolower(getOption("rstudio.notebook.executing", "false")) == "true") {
    FALSE
  } else if (identical(Sys.getenv("TESTTHAT"), "true")) {
    FALSE
  } else {
    interactive()
  }
}
