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

# dat1
set.seed(1)
exp1 <- array(rnorm(60), dim = c(member = 3, sdate = 10, lat = 2))
set.seed(2)
obs1 <- array(rnorm(20), dim = c(sdate = 10, lat = 2))
set.seed(3)
weights1 <- array(abs(rnorm(30)), dim = c(member = 3, sdate = 10))

# dat1_2: probabilites
exp1_2 <- GetProbs(exp1, memb_dim = 'member')
obs1_2 <- GetProbs(obs1, memb_dim = NULL)

# dat2
set.seed(1)
exp2 <- array(rnorm(20), dim = c(member = 2, sdate = 10))
set.seed(2)
obs2 <- array(rnorm(10), dim = c(sdate = 10))

# dat2_1
set.seed(1)
exp2_1 <- array(rnorm(20), dim = c(member = 2, sdate = 10))
set.seed(2)
obs2_1 <- array(rnorm(10), dim = c(member = 1, sdate = 10))

# dat3
set.seed(1)
exp3 <- array(rnorm(40), dim = c(member = 2, sdate = 10, dataset = 2))
set.seed(2)
obs3 <- array(rnorm(60), dim = c(member = 3, sdate = 10, dataset = 3))
set.seed(3)
weights3 <-  array(abs(rnorm(30)), dim = c(member = 2, sdate = 10, dataset = 2))

# dat4
exp4 <- exp3
obs4 <- obs3
obs4[2, 1, 1] <- NA
obs4[3, 2, 1] <- NA
exp4[1, 1, 2] <- NA
weights4 <- weights3

##############################################
test_that("1. Input checks", {
  # exp and obs (1)
  expect_error(
  RPS(c()),
  'Parameter "exp" must be a numeric array.'
  )
  expect_error(
  RPS(exp1, c()),
  'Parameter "obs" must be a numeric array.'
  )

  # time_dim
  expect_error(
  RPS(exp1, obs1, time_dim = 1),
  'Parameter "time_dim" must be a character string.'
  )
  expect_error(
  RPS(exp1, obs1, time_dim = 'time'),
  "Parameter 'time_dim' is not found in 'exp' or 'obs' dimension."
  )
  # memb_dim
  expect_error(
  RPS(exp1, obs1, memb_dim = TRUE),
  "Parameter 'memb_dim' must be a character string."
  )
  expect_error(
  RPS(exp1, obs1, memb_dim = 'memb'),
  "Parameter 'memb_dim' is not found in 'exp' dimension."
  )
  # cat_dim
  expect_error(
  RPS(exp1_2, obs1_2, memb_dim = NULL),
  "Only one of the two parameters 'memb_dim' and 'cat_dim' can have value."
  )

  # exp, ref, and obs (2)
  expect_error(
  RPS(exp1, array(1:9, dim = c(sdate = 9))),
  "Parameter 'exp' and 'obs' must have same length of all dimensions except 'memb_dim' and 'dat_dim'."
  )
  # prob_thresholds
  expect_error(
  RPS(exp1, obs1, prob_thresholds = 1),
  "Parameter 'prob_thresholds' must be a numeric vector between 0 and 1."
  )
  # indices_for_clim
  expect_error(
  RPS(exp1, obs1, indices_for_clim = array(1:6, dim = c(2, 3))),
  "Parameter 'indices_for_clim' must be NULL or a numeric vector."
  )
  expect_error(
  RPS(exp1, obs1, indices_for_clim = 3:11),
  "Parameter 'indices_for_clim' should be the indices of 'time_dim'."
  )
  # Fair
  expect_error(
  RPS(exp1, obs1, Fair = 1),
  "Parameter 'Fair' must be either TRUE or FALSE."
  )
  # nmemb
  expect_error(
  RPS(exp1, obs1, nmemb = "test"),
  "Parameter 'nmemb' must be a single numeric value."
  )
  # cross.val
  expect_error(
  RPS(exp1, obs1, cross.val = 1),
  "Parameter 'cross.val' must be either TRUE or FALSE."
  )
  # weights
  expect_error(
  RPS(exp1, obs1, weights = c(0, 1)),
  "Parameter 'weights' must be a named numeric array."
  )
  expect_error(
  RPS(exp1, obs1, weights = array(1, dim = c(member = 3, time = 10))),
  "Parameter 'weights' must have two dimensions with the names of 'memb_dim' and 'time_dim'."
  )
  expect_error(
  RPS(exp1, obs1, weights = array(1, dim = c(member = 3, sdate = 1))),
  "Parameter 'weights' must have the same dimension lengths as 'memb_dim' and 'time_dim' in 'exp'."
  )
  expect_error(
  RPS(exp3, obs3, weights = array(1, dim = c(member = 3, time = 10, dataset = 3)), dat_dim = 'dataset'),
  "Parameter 'weights' must have three dimensions with the names of 'memb_dim', 'time_dim' and 'dat_dim'."
  )
  # ncores
  expect_error(
  RPS(exp2, obs2, ncores = 1.5),
  "Parameter 'ncores' must be either NULL or a positive integer."
  )

})

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

  expect_equal(
  dim(RPS(exp1, obs1)),
  c(lat = 2)
  )
  expect_equal(
  as.vector(RPS(exp1, obs1)),
  c(0.3555556, 0.4444444),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, Fair = T)),
  c(0.2000000, 0.2666667),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, indices_for_clim = 3:5)),
  c(0.5000000, 0.4666667),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, prob_thresholds = seq(0.1, 0.9, 0.1))),
  c(1.600000, 1.888889),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, weights = weights1)),
  c(0.3692964, 0.5346627),
  tolerance = 0.0001
  )
  expect_equal(
  dim(RPS(exp1, obs1, cross.val = T)),
  c(lat = 2)
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, cross.val = T)),
  c(0.3111111, 0.5333333),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1, cross.val = T, weights = weights1)),
  c(0.3559286, 0.6032109),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp1, obs1)),
  as.vector(RPS(exp1_2, obs1_2, memb_dim = NULL, cat_dim = 'bin'))
  )

})

##############################################
test_that("3. Output checks: dat2", {

  expect_equal(
  dim(RPS(exp2, obs2)),
  NULL
  )
  expect_equal(
  RPS(exp2, obs2),
  0.75,
  tolerance = 0.0001
  )
  expect_equal(
  RPS(exp2, obs2, indices_for_clim = 2:5, prob_thresholds = seq(0.1, 0.9, 0.1)),
  2.75,
  tolerance = 0.0001
  )
  expect_equal(
  RPS(exp2, obs2),
  RPS(exp2_1, obs2_1)
  )
})

##############################################
test_that("4. Output checks: dat3", {

  expect_equal(
  dim(RPS(exp3, obs3, dat_dim = 'dataset')),
  c(nexp = 2, nobs = 3)
  )
  expect_equal(
  as.vector(RPS(exp3, obs3, dat_dim = 'dataset')),
  c(0.3388889, 0.3388889, 0.2944444, 0.3277778, 0.3388889, 0.3388889),
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(RPS(exp3, obs3, dat_dim = 'dataset', indices_for_clim = 2:5, prob_thresholds = seq(0.1, 0.9, 0.1))),
  c(1.394444, 1.394444, 1.250000, 1.316667, 1.394444, 1.394444),
  tolerance = 0.0001
  )
  # weights
  expect_equal(
  dim(RPS(exp3, obs3, weights = weights3, dat_dim = 'dataset')),
  c(nexp = 2, nobs = 3)
  )
  expect_equal(
  as.vector(RPS(exp3, obs3, weights = weights3, dat_dim = 'dataset')),
  c(0.3255765, 0.4290578, 0.2917297, 0.3554689, 0.3255765, 0.4290578),
  tolerance = 0.0001
  )

})

##############################################
test_that("5. Output checks: dat4", {

  res1 <- RPS(exp4, obs4, dat_dim = 'dataset')

  expect_equal(
  which(is.na(res1)),
  c(1, 2, 4, 6)
  )
  expect_equal(
  res1[1, 2:3],
  RPS(exp3, obs3, dat_dim = 'dataset')[1, 2:3]
  )

  res2 <- RPS(exp4, obs4, dat_dim = 'dataset', na.rm = T)

  expect_equal(
  res2,
  RPS(exp4, obs4, dat_dim = 'dataset', na.rm = 0)
  )
  expect_equal(
  which(is.na(res2)),
  integer(0)
  )
  expect_equal(
  c(res2),
  c(0.3472222, 0.3680556, 0.2944444, 0.3333333, 0.3388889, 0.2222222),
  tolerance = 0.0001
  )

  expect_equal(
  RPS(exp4, obs4, dat_dim = 'dataset', na.rm = 0.8),
  res2
  )
  expect_equal(
  RPS(exp4, obs4, dat_dim = 'dataset', na.rm = 0.95),
  res1
  )
  expect_equal(
  which(is.na(RPS(exp4, obs4, dat_dim = 'dataset', na.rm = 0.9))),
  c(1, 2)
  )

  # weights
  res3 <- RPS(exp4, obs4, weights = weights4, dat_dim = 'dataset')
  expect_equal(
  which(is.na(res3)),
  c(1, 2, 4, 6)
  )
  expect_equal(
  res3[1, 2:3],
  RPS(exp3, obs3, dat_dim = 'dataset',weights = weights3)[1, 2:3]
  )

  res4 <- RPS(exp4, obs4, weights = weights4, dat_dim = 'dataset', na.rm = 0)
  expect_equal(
  c(res4),
  c(0.3865228, 0.4885273, 0.2917297, 0.4143631, 0.3255765, 0.4028817),
  tolerance = 0.0001
  )

  expect_equal(
  which(is.na(RPS(exp4, obs4, weights = weights4, dat_dim = 'dataset', na.rm = 0.9))),
  c(1, 2)
  )

})

