#!/usr/bin/Rscript
"usage: report.R [options]

options:

--engine=<string>           packrat or liftr (docker in docker) or NA [default: packrat]
--shinyTemplate=<file>      Shinay app template as zipped(.zip) or tar(tar.gz) file.
--knitrTemplate=<file>      Rmarkdown file template will be rendered by knitr.
--data=<file>               Files to be included in data folder under app folder.
--www=<file>                Files to be included in www folder under app folder.
--src=<file>                Files to be included in src folder under app folder.
--appFiles=<file>           Files to be included in root at your app folder.
--setAccountInfo=<string>   shinyapps::setAccountInfo
--name=<string>             Name of account to save or remove, check shinyapps::setAccountInfo
--token=<string>            User token for the account, check shinyapps::setAccountInfo
--secret=<string>           User secret for the account, check shinyapps::setAccountInfo
--contentCategory=<string>  Optional; the kind of content being deployed (e.g. 'plot', 'document', or 'application').
--account=<string>          Account to deploy application to. This parameter is only required for the initial deployment of an application when there are multiple accounts configured on the system (see accounts).
--server=<string>           Server name. Required only if you use the same account name on multiple servers.
--quiet                     Request that no status information be printed to the console during the deployment.
" -> doc

.curPath <- normalizePath(".")

library("docopt")
# a hack for packrat
install.packages(c("shiny", "rsconnect", "packrat"), repos = "https://cloud.r-project.org/", quiet = TRUE)

opts <- docopt(doc)
deFiles <- function(x, split = ",") {
  strsplit(x, split)[[1]]
}

engine <- opts$engine

# make working directory
app_name <- function(x, prefix = NULL, suffix = NULL, ...) {
  nm <- tools::file_path_sans_ext(basename(x), ...)
  paste0(prefix, nm, suffix)
}

copyFiles <- function(fl, opts) {
  appName <- tools::file_path_sans_ext(basename(fl), compression = TRUE)
  # dir.create(appName)
  .fullPath <- file.path(.curPath, appName)
  dir.create(.fullPath, FALSE)

  # copy file over
  if (!is.null(opts$data)) {
    message("copy to data folder")
    .data <- file.path(.fullPath, "data")
    dir.create(.data, FALSE)
    file.copy(deFiles(opts$data), .data, overwrite = TRUE, recursive = TRUE)
  }

  if (!is.null(opts$www)) {
    message("copy to www folder")
    .www <- file.path(.fullPath, "www")
    dir.create(.www, FALSE)
    file.copy(deFiles(opts$www), .www, overwrite = TRUE, recursive = TRUE)
  }

  if (!is.null(opts$src)) {
    message("copy to src folder")
    .src <- file.path(.fullPath, "src")
    dir.create(.src, FALSE)
    file.copy(deFiles(opts$src), .src, overwrite = TRUE, recursive = TRUE)
  }

  if (!is.null(opts$appFiles)) {
    message("copy to root folder")
    file.copy(deFiles(opts$appFiles), file.path(.fullPath))
  }

  .fullPath
}

unpackShiny <- function(input, outdir = NULL) {
  # extract

  appName <- tools::file_path_sans_ext(basename(input), compression = TRUE)
  extName <- tools::file_ext(basename(input))
  if (is.null(outdir)) {
    outdir <- file.path(.curPath, appName)
  }
  dir.create(outdir, FALSE)
  # .d <- tempfile()
  .d <- file.path(.curPath, basename(tempfile()))
  dir.create(.d, FALSE)

  message("Uncompress into ", .d)

  switch(extName,
    zip = {
      unzip(input, exdir = .d)
    },
    gz = {
      untar(input, exdir = .d)
    },
    tar = {
      untar(input, exdir = .d)
    },
    tar.gz = {
      untar(input, exdir = .d)
    }, {
      setwd(.d)
      system(paste("unp", input))
      setwd(.curPath)
    }
  )

  .ds <- list.dirs(.d, recursive = FALSE)

  if (liftr:::is_shinyapp(.d)) {
    cmd <- paste(
      "cp -R", file.path(dirname(.d), basename(.d), "*"),
      outdir
    )
    message(cmd)
    system(cmd)
  } else if (length(.ds) == 1 &&
    liftr:::is_shinyapp(.ds[1])) {
    cmd <- paste(
      "cp -R", file.path(dirname(.ds[1]), basename(.ds[1]), "*"),
      outdir
    )
    message(cmd)
    system(cmd)
  } else {
    warning("it's probably not shiny app")
    cmd <- paste(
      "cp -R", file.path(dirname(.d), basename(.d), "*"),
      outdir
    )
    message(cmd)
    system(cmd)
  }
}

# Set account info for Shiny apps
toDeploy <- TRUE
if (is.null(opts$setAccountInfo)) {
  if (any(is.null(opts$name), is.null(opts$token), is.null(opts$secret))) {
    toDeploy <- FALSE
  } else {
    rs <- paste(
      "rsconnect::setAccountInfo(name =", opts$name, ",",
      "token = ", opts$token, ",",
      "secret = ", opts$secret
    )
  }
} else {
  # allow you to copy-paste from shinyapps.io or other services
  rs <- opts$setAccountInfo
}

# Start with knitr template
if (!is.null(opts$knitrTemplate)) {

  # create rmarkdown
  fls <- deFiles(opts$knitrTemplate)

  sapply(fls, function(x) {
    .fullPath <- copyFiles(x, opts)
    file.copy(x, file.path(.fullPath), overwrite = TRUE, recursive = TRUE)
    x <- file.path(.fullPath, basename(x))
    message("Rendering ...", x)
    switch(engine,
      liftr = {
        library(liftr)
        o <- Onepunch(input = x)
        o$onepunch(script = rs)
      },
      packrat = {
        .dd <- tempfile()
        dir.create(.dd, FALSE)
        # build in temp dir
        file.copy(x, .dd, overwrite = TRUE, recursive = TRUE)
        suppressMessages({
          packrat::init(.dd)
          install.packages(c("shiny", "rmarkdown", "devtools"), repos = "https://cloud.r-project.org/", quiet = TRUE)
          devtools::install_github(c("rstudio/rsconnect", "rstudio/shinyapps"), quiet = TRUE)
        })
        # FIXME
        rmarkdown::render(x, output_dir = .curPath)
        packrat::off()
      }, {
        rmarkdown::render(x, output_dir = .curPath)
      }
    )
  })
}

# Start with Shiny template
if (!is.null(opts$shinyTemplate)) {
  # make working directory

  fls <- deFiles(opts$shinyTemplate)
  sapply(fls, function(x) {
    message("unpacking shiny app ", basename(x), " ...")
    unpackShiny(x)
    .fullPath <- copyFiles(x, opts)


    setwd(.curPath)
    tar.name <- paste0(basename(.fullPath), ".tar")
    message("tarname: ", tar.name)
    tar(tar.name, .fullPath)


    if (toDeploy) {
      switch(engine,
        liftr = {
          system("service docker start")
          library(liftr)

          o <- Onepunch(input = .fullPath)
          o$deploy(script = rs)
        },
        packrat = {
          .dd <- file.path(.curPath, basename(tempfile()))
          dir.create(.dd, FALSE)
          unpackShiny(x, .dd)

          packrat::init(.dd)

          install.packages(c("shiny", "rsconnect"), repos = "https://cloud.r-project.org/", quiet = TRUE)

          rsconnect::setAccountInfo(
            name = opts$name,
            token = opts$token,
            secret = opts$secret
          )
          message("deploy shiny app: ", .fullPath)
          rsconnect::deployApp(.fullPath)
          packrat::off()
        }, {
          message("deploy shiny app: ", .fullPath)
          rsconnect::deployApp(.fullPath)
        }
      )
    }
  })
  message(
    "list.files:\n ",
    paste(list.files(.curPath), collapse = "\n")
  )
}
