###########################################################################/**
# @RdocFunction buildVignette
#
# @title "Builds a vignette"
#
# \description{
#  @get "title" into a PDF or a HTML file.
# }
#
# @synopsis
#
# \arguments{
#   \item{file}{A character string specifying the vignette source file.}
#   \item{dir}{A character string specifying the working directory.}
#   \item{latex}{A logical specifying whether a TeX produced by weave
#     should be compiled by \link{texi2pdf} or not.}
#   \item{tangle}{A logical specifying whether tangle should be run or not.}
#   \item{quiet}{A logical specifying whether weave, \link{texi2pdf}, and
#     tangle should be run in quiet mode or not.}
#   \item{clean}{Remove all files generated by the build, even if there
#     were copies there before.}
#   \item{engine}{An optional @character string specifying the vignette
#     engine to use for building the vignette.  If not specified, it will
#     be inferred from the \code{\\VignetteEngine\{\}} markup in the
#     vignette.  If that is not specified, the \code{"utils::Sweave"}
#     engine will be used.}
#   \item{buildPkg}{An optional @character string specifying the vignette
#     package to use, if the vignette engine does not specify one.}
#   \item{...}{Additional arguments passed to weave and tangle.}
# }
#
# \value{
#   Returns the filename to the final vignette (PDF or HTML) product.
#   If \code{latex = FALSE}, it may be a TeX file.
# }
#
# @author "HB"
#
# \seealso{
#   Since R devel (to become 3.1.0) r63076 (2013-06-27), there is
#   \code{buildVignette()} in the \pkg{tools} package.
# }
#
# @keyword documentation
# @keyword file
# @keyword IO
# @keyword internal
#*/###########################################################################
buildVignette <- function(file, dir = ".", latex = TRUE, tangle = TRUE, quiet = TRUE, clean = TRUE, engine=NULL, buildPkg=NULL, ...) {
    if (getRversion() >= "3.1.0") {
      .Defunct(new="tools::buildVignette")
    }

    ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ### BEGIN: Workaround until buildVignette() is in the 'tools' package.
    ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    .get_vignette_metadata <- import_tools(".get_vignette_metadata")
    vignette_is_tex <- import_tools("vignette_is_tex")
    find_vignette_product <- import_tools("find_vignette_product")
    
    ## vignetteEngine() is exported in tools (>= 3.0.0)
    if (getRversion() < "3.0.0") {
      vignetteEngine <- import_tools("vignetteEngine")
    }

    list.files <- function(..., no..=FALSE) {
      res <- base::list.files(...)
      if (no..) res <- setdiff(res, c(".", ".."))
      res
    }
    ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ### END: Workaround until buildVignette() is in the 'tools' package.
    ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    if (!file_test("-f", file))
        stop("No such file: ", file)

    if (!file_test("-d", dir))
        stop("Cannot set working directory. No such directory: ", dir)

    if (is.null(engine)) {
      # Infer vignette engine from vignette content
      lines <- readLines(file, warn=FALSE)
      engine <- .get_vignette_metadata(lines, "Engine")
      if (length(engine) == 0L)
          engine <- "utils::Sweave"
    }

    # Is vignette builder package specified in engine name?
    parts <- strsplit(engine, split="::", fixed=TRUE)[[1L]]
    if (length(parts) == 2L)
        buildPkg <- c(parts[1L], buildPkg)

    # Load vignette builder package(s), iff specified
    # HB: Should this be done by vignetteEngine()?
    if (length(buildPkg) > 0L)
        for (pkg in buildPkg)
            loadNamespace(pkg)

    # Get the vignette engine
    engine <- vignetteEngine(engine, package=buildPkg)

    # Infer the vignette name
    names <- sapply(engine$pattern, FUN = sub, "", file)
    name <- basename(names[(names != file)][1L])

    # A non-matching filename?
    if (is.na(name))
        stop("The vignette filename ", sQuote(file), " does not match any of the ", sQuote(paste(engine$package, engine$name, sep="::")), " engine's filename patterns (", paste(sQuote(engine$pattern), collapse=", "), ")")

    # Set working directory temporarily
    if (dir != ".") {
      file <- file_path_as_absolute(file)
      wd <- getwd()
      if (is.null(wd))
          stop("current working directory cannot be ascertained")
      setwd(dir)
      on.exit({
          setwd(wd)
      })
    }

    # Record existing files
    origfiles <- list.files(all.files = TRUE)
    if (clean) {
        file.create(".build.timestamp")
    }

    # Sweave
    engine$weave(file, quiet = quiet, ...)
    setwd(dir)  # In case weave/vignette changed it
    output <- find_vignette_product(name, by = "weave", engine = engine)

    # Compile TeX to PDF?
    if(latex && vignette_is_tex(output)) {
        texi2pdf(file = output, clean = FALSE, quiet = quiet)
        final <- find_vignette_product(name, by = "texi2pdf", engine = engine)
    } else
        final <- output

    # Tangle
    if (tangle) {
        engine$tangle(file, quiet = quiet, ...)
        setwd(dir)  # In case tangle changed it
        sources <- find_vignette_product(name, by = "tangle", main = FALSE, engine = engine)
    } else
        sources <- NULL

    # Cleanup
    # NOTE: TeX file is useful for visually impared, cf. JR. Godfrey,
    #       'Statistical Software from a Blind Person's Perspective',
    #       The R Journal, 2013 (to appear).
    keep <- c(output, sources, final)[-1L]
    if (clean) {
        f <- setdiff(list.files(all.files = TRUE, no.. = TRUE), keep)
        newer <- file_test("-nt", f, ".build.timestamp")
        ## some packages create directories
        unlink(f[newer], recursive = TRUE)
    }
    f <- setdiff(list.files(all.files = TRUE, no.. = TRUE), c(keep, origfiles))
    f <- f[file_test("-f", f)]
    file.remove(f)

    final
} # buildVignette()
