#' runArgusBatchFile
#'
#' allows to run batch-files for tau argus given the path to an executable of argus.
#' The provided batch input files can either be created using function \code{\link{createArgusInput}} or
#' can be arbitrarily created. In the latter case, argument \code{obj} should not be specified and not output
#' is returned, the script is just executed in tau-argus.
#'
#' @param obj \code{NULL} or an object of class \code{\link{sdcProblem-class}} that was used to generate the batchfile for argus. If not \code{NULL},
#' this object is used to create correct variable names. Else, only the output from tau-Argus is read and returned as a \code{data.table}. In this case
#' it is possible to run tau-Argus on arbitrarily created batch-files.
#' @param batchF a filepath to an batch-input file created by e.g. \code{\link{createArgusInput}}.
#' @param exe (character) file-path to tau-argus executable
#' @param batchDataDir if different from \code{NULL}, this directory is used to look for input-file and writes output files to.
#' This helps to use relative paths in batch input files.
#' @param verbose (logical) if \code{TRUE}, some additional information is printed to the prompt
#' @return a \code{data.table} containing the protected table or an error in case the batch-file was not solved correctly
#' if the batch-file was created using sdcTable (argument \code{obj}) was specified. In
#' case an arbitrarily batch-file has been run, \code{NULL} is returned.
#' @note in case a custom batch-file is used as input (e.g \code{obj} is \code{NULL}), this
#' functions does currently not try to read in any tables to the system.
#' @export
runArgusBatchFile <- function(obj=NULL, batchF, exe="C:\\Tau\\TauArgus.exe", batchDataDir=NULL, verbose=FALSE) {
  ## checks
  if(!file.exists(batchF)) {
    stop("argument 'batchF' does not exist!\n")
  }
  if (!file.exists(exe)) {
    stop("the supplied patch to the tau-argus executable does not exist!\n")
  }
  if (!is.null(batchDataDir)) {
    batchDataDir <- batchDataDir[1]
    if (file.access(batchDataDir, mode=2)!=0) {
      stop("directory provided in argument 'batchDataDir' is either-non existing or not writable!\n")
    }
  }

  ## checks
  if (!is.null(obj)) {
    if (!inherits(obj, "sdcProblem")) {
      stop("argument 'obj' must be of class 'sdcProblem'!\n")
    }
    ## check if it was written by sdcTable
    if (readLines(batchF, warn=FALSE)[1]!="//This batch file was generated by sdcTable") {
      stop("the provided batch-file was not created from sdcTable!\n")
    }
  } else {
    # restriction in cae of free input: the batch-file must contain a <LOGBOOK> entry
    inpO <- readLines(batchF, warn=FALSE)
    inp <- inpO[grep("LOGBOOK", inpO)]
    if (length("inp")!=1) {
      stop("the provided batch-input file must contain a <LOGBOOK> entry!\n")
    }
  }

  basedir_tauexe <- dirname(exe)
  logf <- infoFromBatch(batchF, typ="LOGBOOK")
  if (dirname(logf)==".") {
    if (!is.null(batchDataDir)) {
      logf <- file.path(batchDataDir, logf)
    } else {
      logf <- file.path(basedir_tauexe, logf)
    }
  }

  if (!is.null(obj)) {
    outtab <- infoFromBatch(batchF, typ="WRITETABLE")
    # relativPath
    if (dirname(outtab)==".") {
      outtab <- file.path(basedir_tauexe, outtab)
    }
  }

  ## run and check for success
  if (!is.null(batchDataDir)) {
    cmd <- paste(shQuote(exe), shQuote(batchF), "- -", shQuote(batchDataDir))
  } else {
    cmd <- paste(shQuote(exe), shQuote(batchF))
  }

  res <- suppressWarnings(system(cmd, intern=TRUE, ignore.stdout=TRUE, ignore.stderr=FALSE))
  s <- attributes(res)$status
  if (!is.null(s) && s!=0) {
    stop(paste0("An error has occured. Please have a look at the logfile located at ", dQuote(logf),".\n"))
  }

  ## everything ok (and batch-file was created from sdcTable)
  ## we can read the actual output from argus
  if (!is.null(obj)) {
    out <- read_ArgusSolution(outtab)
    if (!is.null(out)) {
      out <- combineInputs(obj=obj, out, batchF=batchF)
    }
    return(out[])
  }

  # custom batch-file: we just inform the user, where to look
  if (verbose) {
    cat(paste("The batch-file",dQuote(batchF),"has been processed by tau-argus!\n"))
  }
  return(invisible(NULL))
}
