# install_if_missing.r


### FOR MANUAL INSTALL:   ---- NOT CURRENTLY USED, but is usefll
# download & install
di <- function(remoteFile, localFile, quiet=TRUE) {
  remoteFile <- gsub("^\\s*|\\s*$", "", remoteFile)
  if (missing(localFile))
    localFile <- tail(strsplit(remoteFile, "/")[[1]], 1)
  if (!file.exists(localFile))
    download.file(remoteFile, localFile)

  install.packages(localFile, type="source", repos=NULL, quiet=quiet)
}

# debug_detach <- TRUE

detach_pkg <- function(pkg) {
  pkg <- gsub("^.*/", "", pkg)
  loaded_pkgs <- search()
  # browser(expr = isTRUE(debug_detach))
  for (p in grep(paste0(":", pkg, "$"), loaded_pkgs, value=TRUE))
    detach(p, character.only=TRUE)
  return(NULL)
}

is.installed <- function(pkg) {
  pkg <- gsub("^.*/", "", pkg)
  return(pkg %in% rownames(installed.packages()))
}

## INSTALL GITHUB Packages
install_using_dv_github <- function(pkg, warn_if_devtools_missing=getOption("warn_if_devtools_missing", TRUE), quiet=TRUE) {
  if (!(shh(require(devtools)))) {
    if (warn_if_devtools_missing)
      warning ("Could not install GitHubInstalls because devtools is not properly installed")
    options("warn_if_devtools_missing" = FALSE)
    return(FALSE)
  }

  try(install_github(repo=sprintf("%s/%s", u, GitHubInstalls[[u]]), quiet=quiet), silent=TRUE)

  pkg.nm <- gsub("^.*/", "", pkg)

  ret <- require(pkg.nm, character.only=TRUE)
  if (ret)
    try(detach_pkg(pkg.nm))

  return(ret)
}

install_if_missing <- function(pkg, system_installer=ifelse(Sys.info()[["sysname"]] == "Darwin", "brew install --env=std", "sudo yum -y install"), attach_after_install=FALSE, update_if_exists=TRUE, quiet=TRUE, verbose=TRUE) {
  if (length(pkg) > 1)
    return(sapply(pkg, install_if_missing))

  ## Cleanup github name so that we dont have to modify rest of code
  pkg.git <- pkg
  pkg <- gsub("^.*/", "", pkg)

  if (is.installed(pkg)) {
    ret <- sprintf("%30s ::  [ ALREADY INSTALLED ]", pkg)
    if (verbose) message(ret)
    update.packages(oldPkgs=pkg, ask=FALSE, quiet=quiet)
    return(TRUE)
  } 

  if (exists("pkgsToInstall") && pkg %ni% pkgsToInstall) {
    ret <- sprintf("%30s ::  [ NOT FLAGGED FOR INSTALL ]", pkg)
    if (verbose) message(ret)
    return(FALSE)
  } 

  ## Note that if the function reached this point then the R package is not installed yet. 
  if (pkg %in% names(system_dependencies)) {
    message ("----- Attempting to install system dependencies for '", pkg, "' ----- ")
    cmd <- sprintf("%s %s", system_installer, paste0(system_dependencies[[pkg]], collapse=" "))
    cmd.out <- system(cmd, intern=TRUE)
    unavail.sys.pkgs <- grep("No package .* available", cmd.out, value=TRUE)
    if (length(unavail.sys.pkgs)) {
      cat(sprintf("Unavailable packages:   %s\n", paste0(gsub("(^.*No package )(.*)( available.*$)", "\\2", unavail.sys.pkgs), collapse="   ")))
    }
    invisible(NULL)
  }

  ## USE GIThUB
  if (pkg.git != pkg)
    return(install_using_dv_github(pkg, quiet=quiet))

  ## OTHERWISE, TRY TO INSTALL
  attempt_with_depends <- try(install.packages(pkg, repos=cranMir, dependencies=TRUE, clean=TRUE, Ncpus=Ncpus, quiet=quiet), silent=TRUE)

  ## If failed, try again, but without dependencies and with only one core (ie, Ncpus=1)
  if (inherits(attempt_with_depends, "try-error"))
    attempt_two <-  try(install.packages("devtools", repos=cranMir, dependencies=FALSE, clean=TRUE, Ncpus=1L, quiet=quiet), silent=TRUE)

  ## Check if the package can be loaded
  if (suppressWarnings(shh(require(pkg, quietly=TRUE, warn=FALSE, character.only=TRUE)))) {
    ## SUCCESS! 
    if (!attach_after_install)
      try(detach_pkg(pkg))
    ret <- sprintf("%30s ::  [ OK ]", pkg)
    if (verbose) message(ret)
    return(TRUE)
  } else {
    ## COULD NOT LOAD
    ret <- sprintf("%30s ::  [ !x!  FAILED  !x! ]", pkg)
    if (verbose) message(ret)
    return(FALSE)
  }
}