#!/usr/bin/env Rscript

description <- 'Install R packages to a python virtualenv

Include the following in an R script to add "$VIRTUAL_ENV/lib/R.%v-library"
to the library search path:

  #!/usr/bin/env Rscript
  if(Sys.getenv("VIRTUAL_ENV") == ""){ stop("An active virtualenv is required") }
  source(file.path(Sys.getenv("VIRTUAL_ENV"), "bin", "rvenv"))

Also see https://github.com/nhoffman/rvenv

'

default_repos <- "http://cran.fhcrc.org/"

is_main <- function(){
  ## Returns TRUE when this file is executed from the shell as a
  ## script, FALSE when sourced.
  is.null(unlist(lapply(sys.frames(), function(x) x$ofile)))
}

renv <- function(venv=Sys.getenv('VIRTUAL_ENV')){

  if(nchar(venv) > 0){
    lib <- .expand_R_libs_env_var(file.path(venv, 'lib', 'R.%v-library'))
    dir.create(lib, showWarnings=FALSE, recursive=TRUE)
  }else{
    stop('An active virtualenv is required')
  }

  return(lib)
}

main <- function(arguments){
  lib <- renv()
  .libPaths(lib)
  installed <- installed.packages(lib.loc=lib)[,'Package']

  if(!'argparse' %in% installed){
    install.packages('argparse', lib=lib, repos=default_repos,
                     dependencies=TRUE, clean=TRUE, quiet=TRUE)
  }

  suppressPackageStartupMessages(library(argparse, quietly=TRUE))

  parser <- ArgumentParser(
      description=gsub('\n', '\\\\n', description),
      formatter_class='argparse.RawTextHelpFormatter')
  parser$add_argument('packages', help='one or more package names', nargs='*')
  parser$add_argument('-r', '--requirements', help='a file listing packages')
  parser$add_argument('--rm', help='remove listed packages',
                      action='store_true', default=FALSE)
  ## parser$add_argument('--bioc', help='packages are in Bioconductor',
  ##                     action='store_true', default=FALSE)
  parser$add_argument('-U', '--update', help='update existing packages',
                      action='store_true', default=FALSE)
  parser$add_argument('-l', '--list', help='list packages installed locally',
                      action='store_true', default=FALSE)
  parser$add_argument('-e', '--environ', help='print shell command to set R_LIBS',
                      action='store_true', default=FALSE)
  parser$add_argument('-R', '--repos', default=default_repos,
                      help='value for "install.packages(repos)" [%(default)s]')
  parser$add_argument('-v', '--verbose', help='be verbose when installing packages',
                      action='store_true', default=FALSE)

  args <- parser$parse_args(arguments)
  packages <- if(is.list(args$packages)){ character() }else{ args$packages }

  if(!is.null(args$requirements)){
    req <- setdiff(gsub(' ', '', readLines(file('R-requirements.txt'))), '')
    packages <- unique(c(packages, req))
  }

  to_install <- setdiff(packages, installed)

  if(args$environ){
    cat(gettextf('export R_LIBS=%s\n', lib))
  }else if(args$rm){
    remove.packages(args$packages, lib=lib)
  }else if(args$update){
    update.packages(lib.loc=lib, repos=args$repos)
  }else if(args$list){
    cat(gettextf('Packages installed in %s\n', lib))
    print(as.data.frame(installed.packages(lib.loc=lib))[,c('Version'), drop=FALSE])
  }else{

    if(length(to_install) == 0){
      stop('no packages specified or all specified packages already installed')
    }

    install.packages(to_install, lib=lib, repos=args$repos,
                     dependencies=TRUE, clean=TRUE, quiet=!args$verbose)

    ## TODO: implement installation from bioconductor
    ## see https://www.bioconductor.org/packages/release/bioc/html/BiocInstaller.html
    ## suppressPackageStartupMessages(library(BiocInstaller, quietly=TRUE))
    ## biocLite(to_install, lib.loc=lib, suppressUpdates=TRUE)
  }
}

if(is_main()){
  main(commandArgs(trailingOnly=TRUE))
}else{
  .libPaths(renv())
}
