context("s2dv::BrierScore tests")

##############################################
# dat1
set.seed(1)
exp1 <- array(runif(30), dim = c(dataset = 1, member = 3, sdate = 5, ftime = 2))
set.seed(2)
obs1 <- array(round(runif(10)), dim = c(dataset = 1, sdate = 5, ftime = 2))

# dat2
set.seed(1)
exp2 <- runif(10)
set.seed(2)
obs2 <- round(runif(10))


##############################################
test_that("1. Input checks", {
  # exp and obs
  expect_error(
  BrierScore(exp1, c()),
  "Parameter 'exp' and 'obs' cannot be NULL."
  )
  expect_error(
  BrierScore(c('b'), obs1),
  "Parameter 'exp' and 'obs' must be a vector or a numeric array."
  )
  expect_error(
  BrierScore(array(1:10, dim = c(2, 5)), array(1:4, dim = c(2, 2))),
  "Parameter 'exp' and 'obs' must have dimension names."
  )
  expect_error(
  BrierScore(exp = 1:10, obs = obs1),
  "Parameter 'exp' must be within \\[0, 1\\] range."
  )
  expect_error(
  BrierScore(exp1, runif(10)),
  "Parameter 'obs' must be binary events \\(0 or 1\\)."
  )
  expect_error( 
  BrierScore(exp1, obs1),
  paste0("Parameter 'exp' and 'obs' must have the same names and lengths ",
         "of all the dimensions expect 'exp' may have 'memb_dim'.")
  )
  # thresholds
  expect_error(  
  BrierScore(exp2, obs2, thresholds = TRUE),
  "Parameter 'thresholds' must be a numeric vector."
  )
  # time_dim
  expect_error(
  BrierScore(exp2, obs2, time_dim = 1),
  "Parameter 'time_dim' must be a character string."
  )
  expect_error(
  BrierScore(exp1, obs1, memb_dim = 'member', time_dim = 'time'),
  "Parameter 'time_dim' is not found in 'exp' and 'obs' dimension."
  )
  # dat_dim
  expect_error(
  BrierScore(exp1, obs1, dat_dim = 2),
  "Parameter 'dat_dim' must be a character string."
  )
  expect_error(
  BrierScore(exp1, obs1, dat_dim = 'dat'),
  "Parameter 'dat_dim' is not found in 'exp' and 'obs' dimension."
  )
  # memb_dim
  expect_error(
  BrierScore(exp2, obs2, memb_dim = 2),
  "Parameter 'memb_dim' must be a character string."
  )
  expect_error(
  BrierScore(exp2, obs2, memb_dim = 'ensemble'),
  "Parameter 'memb_dim' is not found in 'exp' dimension."
  )
  expect_error(
  BrierScore(exp2, obs2, ncores = 0),
  "Parameter 'ncores' must be a positive integer."
  )

})

##############################################
test_that("2. Output checks: dat1", {

expect_equal(
length(BrierScore(exp1, obs1, memb_dim = 'member')),
16
)
expect_equal(
names(BrierScore(exp1, obs1, memb_dim = 'member')),
c('rel', 'res', 'unc', 'bs', 'bs_check_res', 'bss_res', 'gres',
  'bs_check_gres', 'bss_gres', 'rel_bias_corrected', 'gres_bias_corrected',
  'unc_bias_corrected', 'bss_bias_corrected', 'nk', 'fkbar', 'okbar')
)
expect_equal(
dim(BrierScore(exp1, obs1, memb_dim = 'member')$rel),
c(dataset = 1, ftime = 2)
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$rel[1, ],
c(0.1013649, 0.2549810),
tolerance = 0.0001
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$res[1, ],
c(0.24, 0.24),
tolerance = 0.0001
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$bs[1, ],
c(0.1016759, 0.2549810),
tolerance = 0.0001
)
expect_equal(
dim(BrierScore(exp1, obs1, memb_dim = 'member')$okbar),
c(bin = 10, dataset = 1, ftime = 2)
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$okbar[, 1, 1],
c(NaN, 0, NaN, NaN, 0, NaN, 1, 1, NaN, NaN)
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$fkbar[, 1, 1],
c(NaN, 0.1481059, NaN, NaN, 0.4034953, NaN, 0.6415412, 0.7448624, NaN, NaN),
tolerance = 0.0001
)
expect_equal(
BrierScore(exp1, obs1, memb_dim = 'member')$nk[, 1, 1],
c(0, 1, 0, 0, 1, 0, 2, 1, 0, 0)
)

expect_equal(
dim(BrierScore(exp1, obs1, memb_dim = 'member', dat_dim = 'dataset')$rel),
c(nexp = 1, nobs = 1, ftime = 2)
)
expect_equal(
dim(BrierScore(exp1, obs1, memb_dim = 'member', dat_dim = 'dataset')$nk),
c(nexp = 1, nobs = 1, bin = 10, ftime = 2)
)
expect_equal(
as.vector(BrierScore(exp1, obs1, memb_dim = 'member', dat_dim = 'dataset')$nk),
as.vector(BrierScore(exp1, obs1, memb_dim = 'member')$nk)
)
expect_equal(
as.vector(BrierScore(exp1, obs1, memb_dim = 'member', dat_dim = 'dataset')$bs),
as.vector(BrierScore(exp1, obs1, memb_dim = 'member')$bs)
)
})


##############################################
test_that("3. Output checks: dat2", {
expect_equal(
length(BrierScore(exp2, obs2)),
16
)
expect_equal(
dim(BrierScore(exp2, obs2))$bss,
NULL
)
expect_equal(
length(BrierScore(exp2, obs2)$bss_res),
1
)
expect_equal(
dim(BrierScore(exp2, obs2))$nk,
NULL
) 
expect_equal(
length(BrierScore(exp2, obs2)$nk),
10
)
expect_equal(
BrierScore(exp2, obs2)$bs,
0.4403154,
tolerance = 0.0001
)
expect_equal(
BrierScore(exp2, obs2)$gres_bias_corrected,
0.06313199,
tolerance = 0.0001
)
expect_equal(
BrierScore(exp2, obs2)$bss_bias_corrected,
-0.6511828,
tolerance = 0.0001
)
expect_equal(
as.vector(BrierScore(exp2, obs2)$nk),
c(1, 0, 2, 1, 0, 1, 2, 0, 1, 2)
)

})
