# Usage: Rscript run-harness.R <function-file> <output-dir>
# Sources the given create.sim.dataset implementation, runs a broad set of the
# documented example calls, and saves each return value as an .rds for exact
# cross-version comparison.
args <- commandArgs(trailingOnly = TRUE)
fn.file <- args[1]
out.dir <- args[2]
# Optional 3rd arg: comma-separated case names to run (others skipped). Useful for
# fast iteration on the small datasets before a full run.
only <- if (length(args) >= 3 && nzchar(args[3])) strsplit(args[3], ",")[[1]] else NULL
dir.create(out.dir, showWarnings = FALSE, recursive = TRUE)

source('test/setup-data.R')   # defines param, param2, param3, st.* (loads data.table)
source(fn.file)               # defines create.sim.dataset (+ helpers)

run <- function(name, expr) {
  if (!is.null(only) && !(name %in% only)) return(invisible())
  res <- tryCatch(
    withCallingHandlers(
      eval.parent(substitute(expr)),
      warning = function(w) invokeRestart("muffleWarning"),
      message = function(m) invokeRestart("muffleMessage")
    ),
    error = function(e) structure(list(error = conditionMessage(e)), class = "harness.error")
  )
  if (inherits(res, "harness.error")) {
    cat(sprintf("  [ERROR] %-14s : %s\n", name, res$error))
  } else {
    cat(sprintf("  [ok]    %-14s\n", name))
  }
  saveRDS(res, file.path(out.dir, paste0(name, ".rds")))
  invisible(res)
}

common <- list(export = FALSE, skip.dir.check = TRUE)

run("sim", create.sim.dataset(read.dose.info=F, di=336, num.dose=3, dose=3, dose.unit=c('mg/kg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.2w), smp.time.as.is=F, inf.time=0.5,
  auc.interval=T, auc.cmt=3, cov.df=param, id.var='ID', bw.var='BBWT', output.suffix=NULL, export=FALSE,
  ss=TRUE, ss.with.addl=TRUE, addl=100, auc.ss.interval=FALSE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=4, skip.dir.check=TRUE))

run("sim1", create.sim.dataset(read.dose.info=F, di=c(0,336), num.dose=c(1,2), dose=c(3,200), dose.unit=c('mg/kg','mg'),
  dose.cmt=c(2,1), obs.cmt=1, smp.time=list(NA, st.2w), smp.time.as.is=F, inf.time=c(-1,1),
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s1', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=1, skip.dir.check=TRUE))

run("sim2", create.sim.dataset(read.dose.info=F, di=c(336,504,672), num.dose=2, dose=c(3,240,10), dose.unit=c('mg/kg','mg','mg/kg'),
  dose.cmt=c(1,1,2), obs.cmt=c(1), smp.time=list(st.2w, st.3w, st.4w), smp.time.as.is=F, inf.time=c(1,0.5,2),
  auc.interval=T, auc.cmt=c(3,5), cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s2', export=FALSE,
  ss=TRUE, smp.time.ss=NA, only.ss=FALSE, num.dose.ss=2, skip.dir.check=TRUE))

run("sim3", create.sim.dataset(read.dose.info=T, di='DOSEINT', num.dose=3, dose='NDOSE', dose.unit='DU',
  dose.cmt='DOSECMT', obs.cmt=1, smp.time=list(st.2w, st.3w), smp.time.as.is=F, inf.time='INFTIME',
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s3', export=FALSE,
  ss=TRUE, smp.time.ss=NA, only.ss=FALSE, num.dose.ss=2, skip.dir.check=TRUE))

run("sim4", create.sim.dataset(read.dose.info=F, di=c(504,672), num.dose=c(6,9), dose=c(360,480), dose.unit=c('mg','mg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.3w, st.4w), smp.time.as.is=F, inf.time=0.5,
  auc.interval=T, auc.cmt=3, cov.df=param, id.var='ID', bw.var='BBWT', output.suffix='s4', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=1, skip.dir.check=TRUE))

run("sim5", create.sim.dataset(read.dose.info=F, di=336, num.dose=26, dose=3, dose.unit=c('mg/kg'),
  dose.cmt=1, sec.dose.cmt=2, obs.cmt=1, smp.time=list(st.2w), smp.time.as.is=F, inf.time=NA, sec.inf.time=-2,
  auc.interval=T, auc.cmt=3, cov.df=param, id.var='ID', bw.var='BBWT', output.suffix='s5', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=4, skip.dir.check=TRUE))

run("sim6", create.sim.dataset(read.dose.info=F, di=672, num.dose=13, dose=480, dose.unit=c('mg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.4w), smp.time.as.is=F, inf.time=1,
  auc.interval=T, auc.cmt=3, cov.df=param, id.var='ID', bw.var='BBWT', output.suffix='s6', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=2, skip.dir.check=TRUE))

run("sim7", create.sim.dataset(read.dose.info=F, di=1344, num.dose=7, dose=960, dose.unit=c('mg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.8w), smp.time.as.is=F, inf.time=1,
  auc.interval=T, auc.cmt=3, cov.df=param, id.var='ID', bw.var='BBWT', output.suffix='s7', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=1, skip.dir.check=TRUE))

run("sim8", create.sim.dataset(read.dose.info=T, di='DOSEINT', num.dose='NUMDOSE', dose='NDOSE', dose.unit='DU',
  dose.cmt='DOSECMT', obs.cmt=1, smp.time=list(st.2w, st.3w), smp.time.as.is=F, inf.time='INFTIME',
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s8', export=FALSE,
  ss=TRUE, ss.with.addl=TRUE, addl=100, auc.ss.interval=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=3, skip.dir.check=TRUE))

run("sim9", create.sim.dataset(read.dose.info=F, di=336, num.dose=3, dose=3, dose.unit='mg/kg',
  dose.cmt=1, sec.dose.cmt=2, obs.cmt=1, smp.time=list(st.2w), smp.time.as.is=F, inf.time=NA, sec.inf.time=-2,
  auc.interval=T, auc.cmt=c(3,5), cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s9', export=FALSE,
  ss=TRUE, ss.with.addl=T, addl=100, auc.ss.interval=T, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=2, skip.dir.check=TRUE))

run("sim8b", create.sim.dataset(read.dose.info=T, di='DOSEINT', num.dose='NUMDOSE', dose='NDOSE', dose.unit='DU',
  dose.cmt='DOSECMT', sec.dose.cmt='SDOSECMT', obs.cmt=1, smp.time=list(st.2w, st.3w), smp.time.as.is=F, inf.time='INFTIME', sec.inf.time='SINFTIME',
  auc.interval=T, auc.cmt=3, cov.df=param3, id.var='ID', bw.var='BBWT', output.suffix='s8b', export=F,
  ss=T, ss.with.addl=T, addl=100, auc.ss.interval=T, smp.time.ss=list(c(1,2,3,504), c(2,4,6,336)), only.ss=F, num.dose.ss='NUMDOSE', skip.dir.check=TRUE))

run("sim9b", create.sim.dataset(read.dose.info=F, di=c(504), num.dose=2, dose=c(3), dose.unit=c('mg/kg'),
  dose.cmt=2, obs.cmt=1, smp.time=NULL, smp.time.as.is=F, inf.time=0.5,
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s9b', export=F,
  ss=T, ss.with.addl=T, addl=100, auc.ss.interval=T, smp.time.ss=list(c(1,2,3,504)), only.ss=T, num.dose.ss=3, skip.dir.check=TRUE))

run("sim10", create.sim.dataset(read.dose.info=F, di=336, num.dose=rep(c(1,1,1),4), dose=rep(c(0,1,5),4), dose.unit=c('mg/kg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.2w), inf.time=rep(c(0,1,0.5),4),
  auc.interval=c(T), auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s10', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=3, skip.dir.check=TRUE))

run("sim.qd", create.sim.dataset(read.dose.info=F, di=rep(c(24,96,48),3), num.dose=rep(c(5,1,3),3), dose=rep(c(3,0,3),3), dose.unit=c('mg/kg'),
  dose.cmt=1, obs.cmt=2, smp.time=rep(list(st.qd, st.q4d, st.q2d),3), inf.time=1,
  auc.interval=rep(c(T,F,T),3), auc.cmt=c(3,5,7), cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='qd', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=4, skip.dir.check=TRUE))

run("sim.bigAUCINT", create.sim.dataset(read.dose.info=F, di=24, num.dose=c(5,2,3), dose=3, dose.unit=c('mg/kg'),
  dose.cmt=1, obs.cmt=1, smp.time=list(st.qd), inf.time=1,
  auc.interval=c(T,F,T), auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='bigAUCINT', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, only.ss=FALSE, num.dose.ss=4, skip.dir.check=TRUE))

run("sim11", create.sim.dataset(read.dose.info=T, di='DOSEINT', num.dose='NUMDOSE', dose='NDOSE', dose.unit='DU',
  dose.cmt='DOSECMT', sec.dose.cmt='SDOSECMT', obs.cmt=1, smp.time=list(st.2w, st.3w), smp.time.as.is=F, inf.time='INFTIME', sec.inf.time='SINFTIME',
  auc.interval=T, auc.cmt=3, cov.df=param3, id.var='ID', bw.var='BBWT', output.suffix='s11', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, ss.with.addl=F, addl=NULL, only.ss=T, num.dose.ss=3, skip.dir.check=TRUE))

run("sim11b", create.sim.dataset(read.dose.info=T, di='DOSEINT', num.dose='NUMDOSE', dose='NDOSE', dose.unit='DU',
  dose.cmt='DOSECMT', sec.dose.cmt='SDOSECMT', obs.cmt=1, smp.time=list(st.2w, st.3w), smp.time.as.is=F, inf.time='INFTIME', sec.inf.time='SINFTIME',
  auc.interval=T, auc.cmt=3, cov.df=param3, id.var='ID', bw.var='BBWT', output.suffix='s11b', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, ss.with.addl=T, addl=100, only.ss=T, num.dose.ss=3, skip.dir.check=TRUE))

run("sim12", create.sim.dataset(read.dose.info=F, di=c(336,504,336), num.dose=c(2,2,3), dose=c(240,3,10), dose.unit=c('mg','mg/kg','mg/kg'),
  dose.cmt=1, sec.dose.cmt=c(NA,2,2), obs.cmt=2, smp.time=list(st.2w, st.3w, st.2w), smp.time.as.is=F, inf.time=c(-1,NA,NA), sec.inf.time=c(NA,-2,-2),
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s12', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, ss.with.addl=F, addl=NULL, only.ss=F, num.dose.ss=3, skip.dir.check=TRUE))

run("sim12b", create.sim.dataset(read.dose.info=F, di=c(336,504,336), num.dose=c(2,2,3), dose=c(240,3,10), dose.unit=c('mg','mg/kg','mg/kg'),
  dose.cmt=1, sec.dose.cmt=c(NA,2,2), obs.cmt=2, smp.time=list(st.2w, st.3w, st.2w), smp.time.as.is=F, inf.time=c(-1,NA,NA), sec.inf.time=c(NA,-2,-2),
  auc.interval=T, auc.cmt=3, cov.df=param2, id.var='ID', bw.var='BBWT', output.suffix='s12b', export=FALSE,
  ss=TRUE, smp.time.ss=NULL, ss.with.addl=T, addl=100, only.ss=TRUE, num.dose.ss=3, skip.dir.check=TRUE))

cat('DONE\n')
