context("CSTools::CST_MultiMetric")

################################################################################

# dat
mod <- 1 : (2 * 3 * 4 * 5 * 6 * 8)
dim(mod) <- c(dataset = 2, member = 3, sdate = 4, ftime = 5, lat = 6, lon = 8)
obs <- 1 : (1 * 1 * 4 * 5 * 6 * 8)
dim(obs) <- c(dataset = 1, member = 1, sdate = 4, ftime = 5, lat = 6, lon = 8)
lon <- seq(0, 30, 5)
lat <- seq(0, 30, 5)
coords <- list(lon = lon, lat = lat)
exp <- list(data = mod, coords = coords)
obs <- list(data = obs, coords = coords)
attr(exp, 'class') <- 's2dv_cube'
attr(obs, 'class') <- 's2dv_cube'

################################################################################

test_that("1. Sanity checks", {
  expect_error(
    CST_MultiMetric(exp = 1),
    paste0("Parameter 'exp' and 'obs' must be of the class 's2dv_cube', ",
         "as output by CSTools::CST_Load.")
  )
  expect_error(
    CST_MultiMetric(exp = exp, obs = obs, metric = 1),
    paste0("Parameter 'metric' must be a character string indicating one ",
           "of the options: 'correlation', 'rms', 'rmsss' or 'rpss'")
  )
  expect_error(
    CST_MultiMetric(exp = exp, obs = obs, metric = NA),
    "missing value where TRUE/FALSE needed"
  )
  expect_error(
    CST_MultiMetric(exp = exp, obs = obs, metric = NULL),
    "argument is of length zero"
  )
  expect_error(
    CST_MultiMetric(exp = exp, obs = obs, metric = "correlation", multimodel = NULL),
    "Parameter 'multimodel' must be a logical value."
  )
  expect_error(
    MultiMetric(exp = array(rnorm(10)), obs = array(rnorm(10)), metric = "rpss",
                multimodel = TRUE),
    "Element 'data' from parameters 'exp' and 'obs' should have dimension names."
  )
  expect_error(
    MultiMetric(exp = array(rnorm(10), dim = c(sdate = 10)), 
                obs = array(rnorm(10), dim = c(time = 10)), 
                metric = "rpss", multimodel = TRUE),
    paste0("Dimension names of element 'data' from parameters 'exp' and ",
           "'obs' should have the same name dimmension.")
  )
})  

################################################################################

test_that("2. Basic use case", {
  
  corr <- array(rep(1, 3* 48), dim = c(nexp = 3, nobs = 1, lat = 6, lon = 8))
  p.val <- array(rep(0, 3 * 48), dim = c(nexp = 3, nobs = 1, lat = 6, lon = 8))
  conf.lower <- array(rep(1, 3* 48), dim = c(nexp = 3, nobs = 1, lat = 6, lon = 8))
  conf.upper = array(rep(1, 3* 48), dim = c(nexp = 3, nobs = 1, lat = 6, lon = 8))

  data <- list(corr = corr, p.val = p.val, conf.lower = conf.lower, conf.upper = conf.upper)
  result <- list(data = data, coords = coords) 
  attr(result, 'class') <- 's2dv_cube'

  expect_equal(
    CST_MultiMetric(exp = exp, obs = obs), 
    result
  )
  
  exp2 <- exp
  exp2$data[1, 1, 1, 2, 1, 1] <- NA
  res <- CST_MultiMetric(exp = exp, obs = obs, metric = 'rms')

  expect_equal(
    length(res), 
    2
  )
  expect_equal(
    dim(res$data$rms), 
    c(nexp = 3, nobs = 1, lat = 6, lon = 8)
  )
  res <- CST_MultiMetric(exp = exp, obs = obs, metric = 'rms', 
                         multimodel = FALSE)
  expect_equal(
    dim(res$data$rms), 
    c(nexp = 2, nobs = 1, lat = 6, lon = 8)
  )
  expect_equal(
    length(res$data), 
    3
  )
  res <- CST_MultiMetric(exp = exp, obs = obs, metric = 'rmsss')
  expect_equal(
    dim(res$data$rmsss), 
    c(nexp = 3, nobs = 1, lat = 6, lon = 8)
  )
  res <- CST_MultiMetric(exp = exp, obs = obs, metric = 'rmsss', multimodel = FALSE)
  expect_equal(
    dim(res$data$rmsss), 
    c(nexp = 2, nobs = 1, lat = 6, lon = 8)
  )
})