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

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

abs_thr1_1 <- c(-0.2, 0.4)
abs_thr1_2 <- array(abs_thr1_1, dim = c(bin = 2))
set.seed(4)
abs_thr1_3 <- array(abs_thr1_1 + rnorm(20)*0.1, dim = c(bin = 2, sdate = 10))
abs_thr1_4 <- array(abs_thr1_3, dim = c(dim(abs_thr1_3), time = 2))

# dat2
set.seed(1)
data2 <- array(rnorm(20), dim = c(sdate = 10, time = 2))
set.seed(2)
weights2 <- array(abs(rnorm(10)), dim = c(sdate = 10))
abs_thr2_1 <- c(-0.2, 0.4)
abs_thr2_2 <- array(abs_thr2_1, dim = c(bin = 2))
set.seed(4)
abs_thr2_3 <- array(abs_thr2_1 + rnorm(20)*0.3, dim = c(bin = 2, sdate = 10))
abs_thr2_4 <- array(abs_thr2_3, dim = c(dim(abs_thr2_3), time = 2))

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

test_that("1. Input checks", {
  # data
  expect_error(
  GetProbs(c()),
  "Parameter 'data' cannot be NULL."
  )
  expect_error(
  GetProbs(c(data2)),
  "Parameter 'data' must have dimension names."
  )
  # time_dim
  expect_error(
  GetProbs(data1, time_dim = 1),
  'Parameter "time_dim" must be a character string.'
  )
  expect_error(
  GetProbs(data1, time_dim = 'ftime'),
  "Parameter 'time_dim' is not found in 'data' dimensions."
  )
  # memb_dim
  expect_error(
  GetProbs(data1, memb_dim = TRUE),
  "Parameter 'memb_dim' must be a character string."
  )
  expect_error(
  GetProbs(data1, memb_dim = 'memb'),
  "Parameter 'memb_dim' is not found in 'data' dimensions."
  )
  # prob_thresholds
  expect_error(
  GetProbs(data1, prob_thresholds = 1),
  "Parameter 'prob_thresholds' must be a numeric vector between 0 and 1."
  )
  # abs_thresholds
  expect_error(
  GetProbs(data1, prob_thresholds = NULL, abs_thresholds = abs_thr1_2, bin_dim_abs = 'cat'),
  "Parameter abs_thresholds' can be a vector or array with 'bin_dim_abs' dimension."
  )
  expect_error(
  GetProbs(data1, prob_thresholds = NULL, abs_thresholds = array(abs_thr1_3, dim = c(dim(abs_thr1_3), member = 3))),
  "Parameter abs_thresholds' cannot have member dimension."
  )
  expect_error(
  GetProbs(data1, prob_thresholds = NULL, abs_thresholds = array(abs_thr1_3, dim = c(dim(abs_thr1_3), extra = 3))),
  "Parameter 'abs_thresholds' dimensions except 'bin_dim_abs' must be in 'data' as well."
  )
  expect_error(
  GetProbs(data1, prob_thresholds = NULL, abs_thresholds = array(abs_thr1_3, dim = c(bin = 2, sdate = 5, time = 2))),
  "Parameter 'abs_thresholds' dimensions must have the same length as 'data'."
  )
  # indices_for_clim
  expect_error(
  GetProbs(data1, indices_for_quantiles = array(1:6, dim = c(2, 3))),
  "Parameter 'indices_for_quantiles' must be NULL or a numeric vector."
  )
  expect_error(
  GetProbs(data1, indices_for_quantiles = 3:11),
  "Parameter 'indices_for_quantiles' should be the indices of 'time_dim'."
  )
  # cross.val
  expect_error(
  GetProbs(data1, cross.val = 1),
  "Parameter 'cross.val' must be either TRUE or FALSE."
  )
  # weights
  expect_error(
  GetProbs(data1, weights = c(0, 1)),
  "Parameter 'weights' must be a named numeric array."
  )
  expect_error(
  GetProbs(data1, weights = array(1, dim = c(member = 3, time = 10))),
  "Parameter 'weights' must have dimension sdate and member."
  )
  expect_error(
  GetProbs(data1, weights = array(1, dim = c(member = 3, sdate = 1))),
  "Parameter 'weights' must have the same dimension length as sdate and member dimension in 'data'."
  )
#  expect_error(
#  GetProbs(data3, 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(
  GetProbs(data1, ncores = 1.5),
  "Parameter 'ncores' must be either NULL or a positive integer."
  )

})

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

expect_equal(
dim(GetProbs(data1)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
dim(GetProbs(data1, bin_dim_abs = "cat")),
c(cat = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1)[, 10, 2]),
c(0.3333333, 0.3333333, 0.3333333),
tolerance = 0.0001
)
expect_equal(
c(GetProbs(data1)[, 2, 2]),
c(0.6666667, 0.3333333, 0.0000000),
tolerance = 0.0001
)

# indices_for_quantiles
expect_equal(
dim(GetProbs(data1, indices_for_quantiles = 4:7)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, indices_for_quantiles = 4:7)[, 10, 2]),
c(0.3333333, 0.6666667, 0.0000000),
tolerance = 0.0001
)

# prob_thresholds
expect_equal(
dim(GetProbs(data1, prob_thresholds = c(0.25, 0.5, 0.75))), 
c(bin = 4, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, prob_thresholds = c(0.25, 0.5, 0.75))[, 10, 2]),
c(0.3333333, 0.3333333, 0.3333333, 0.0000000),
tolerance = 0.0001
)
expect_equal(
c(GetProbs(data1, prob_thresholds = c(0.25, 0.5, 0.75))[, 3, 2]),
c(0.0000000, 0.6666667, 0.0000000, 0.3333333),
tolerance = 0.0001
)

# weights
expect_equal(
dim(GetProbs(data1, weights = weights1)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, weights = weights1)[, 10, 2]),
c(0.3327220, 0.5296149, 0.1376631),
tolerance = 0.0001
)
expect_equal(
sum(c(GetProbs(data1, weights = weights1))),
20
)

# cross.val
expect_equal(
dim(GetProbs(data1, cross.val = T)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, cross.val = T)[, 10, 2]),
c(0.3333333, 0.3333333, 0.3333333),
tolerance = 0.0001
)
expect_equal(
c(GetProbs(data1, cross.val = T)[, 4, 2]),
c(0.0000000, 0.6666667, 0.3333333),
tolerance = 0.0001
)

# cross.val + weights
expect_equal(
dim(GetProbs(data1, cross.val = T, weights = weights1)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, cross.val = T, weights = weights1)[, 10, 2]),
c(0.3335612, 0.5277459, 0.1386929),
tolerance = 0.0001
)

# abs_threshold
expect_equal(
dim(GetProbs(data1, abs_thresholds = abs_thr1_1, prob_thresholds = NULL, indices_for_quantiles = NULL)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data1, abs_thresholds = abs_thr1_1, prob_thresholds = NULL, indices_for_quantiles = NULL)[, 3, 2]),
c(0.3333333, 0.3333333, 0.3333333),
tolerance = 0.0001
)
expect_equal(
GetProbs(data1, abs_thresholds = abs_thr1_1, prob_thresholds = NULL, indices_for_quantiles = NULL),
GetProbs(data1, abs_thresholds = abs_thr1_2, prob_thresholds = NULL, indices_for_quantiles = NULL)
)
expect_equal(
c(GetProbs(data1, abs_thresholds = abs_thr1_3, prob_thresholds = NULL, indices_for_quantiles = NULL)[, 3, 2]),
c(0.6666667, 0, 0.3333333),
tolerance = 0.0001
)
expect_equal(
GetProbs(data1, abs_thresholds = abs_thr1_3, prob_thresholds = NULL, indices_for_quantiles = NULL),
GetProbs(data1, abs_thresholds = abs_thr1_4, prob_thresholds = NULL, indices_for_quantiles = NULL)
)

})


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

expect_equal(
dim(GetProbs(data2, memb_dim = NULL)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL)[, 10, 2]),
c(0, 1, 0)
)
expect_equal(
unique(c(GetProbs(data2, memb_dim = NULL))),
c(1, 0)
)

# indices_for_quantiles
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, indices_for_quantiles = 4:7)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, indices_for_quantiles = 4:7)[, 10, 2]),
c(0, 0, 1)
)

# prob_thresholds
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, prob_thresholds = c(0.25, 0.5, 0.75))),
c(bin = 4, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, prob_thresholds = c(0.25, 0.5, 0.75))[, 10, 2]),
c(0, 0, 1, 0)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, prob_thresholds = c(0.25, 0.5, 0.75))[, 3, 2]),
c(1, 0, 0, 0)
)

# weights
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, weights = weights2)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, weights = weights2)[, 10, 2]),
c(0, 1, 0)
)
expect_equal(
sum(c(GetProbs(data2, memb_dim = NULL, weights = weights2))),
20
)

# cross.val
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, cross.val = T)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, cross.val = T)[, 10, 2]),
c(0, 1, 0)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, cross.val = T)[, 4, 2]),
c(1, 0, 0)
)

# cross.val + weights
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, cross.val = T, weights = weights2)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, cross.val = T, weights = weights2)[, 10, 2]),
c(0, 1, 0)
)

# abs_threshold
expect_equal(
dim(GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_1, prob_thresholds = NULL, indices_for_quantiles = NULL)),
c(bin = 3, sdate = 10, time = 2)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_1, prob_thresholds = NULL, indices_for_quantiles = NULL)[, 5, 1]),
c(0, 1, 0),
tolerance = 0.0001
)
expect_equal(
GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_1, prob_thresholds = NULL, indices_for_quantiles = NULL),
GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_2, prob_thresholds = NULL, indices_for_quantiles = NULL)
)
expect_equal(
c(GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_3, prob_thresholds = NULL, indices_for_quantiles = NULL)[, 5, 1]),
c(1, 0, 0),
tolerance = 0.0001
)
expect_equal(
GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_3, prob_thresholds = NULL, indices_for_quantiles = NULL),
GetProbs(data2, memb_dim = NULL, abs_thresholds = abs_thr2_4, prob_thresholds = NULL, indices_for_quantiles = NULL)
)

})
