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

# dat1
data <- rnorm(2 * 10 * 4 * 5 * 6 * 7)
dim(data) <- c(dataset = 2, member = 10,
                sdate = 4, ftime = 5, lat = 6, lon = 7)
lon <- seq(0, 12, 2)
lat <- seq(10, 15, 1)
coords <- list(lon = lon, lat = lat)
exp <- list(data = data, coords = coords)
attr(exp, "class") <- "s2dv_cube"

# dat2
exp2 <- exp
exp2$attrs <- list(source_files = 'exp')
exp2$coords <- NULL
exp2_2 <- exp2
exp2_2$coords <- list(long = seq(1:4), lati = seq(1:4))

# data1
data1 <- 1 : 400
dim(data1) <- c(time = 20, lat = 5, lon = 4)
data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
class(data1) <- 's2dv_cube'

##############################################
test_that("1. Input checks", {
  expect_error(
    CST_WeatherRegimes(data = 1),
    paste0("Parameter 'data' must be of the class 's2dv_cube', as output by ",
            "CSTools::CST_Load.")
  )
  # Check 'exp' object structure
  expect_error(
    CST_WeatherRegimes(exp2),
    paste0("Parameter 'data' must have 'data' and 'coords' elements ",
           "within the 's2dv_cube' structure.")
  )
  expect_error(
    CST_WeatherRegimes(exp2_2, ncenters = 3),
    paste0("Spatial coordinate names do not match any of the names accepted ",
           "the package.")
  )
  expect_error(
    WeatherRegime(array(rnorm(8400), dim = c(member = 10, sdate = 4, ftime = 5, 
                                             lati = 6, loni = 7)), 
                  lat = seq(1:5), lon = seq(1:6), ncenters = 3),
    paste0("Spatial coordinate names do not match any of the names accepted by ",
           "the package.")
  )
  data1 <- 1 : 20
  data1 <- list(data = data1, coords = list(lat = 1, lon = 1))
  class(data1) <- 's2dv_cube'
  expect_error(
    CST_WeatherRegimes(data = data1),
    paste0("Parameter 'data' must be an array with named dimensions.")
  )  
  data1 <- 1 : 20
  dim(data1) <- c(lat = 5, lon = 4)
  data1 <- list(data = data1 , coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  expect_error(
    CST_WeatherRegimes(data = data1),
    paste0("Parameter 'data' must have temporal dimensions.")
  )
  data1 <- 1 : 400
  dim(data1) <- c(time = 20, lat = 5, lon = 4)
  data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  expect_error(
    CST_WeatherRegimes(data = data1),
    paste0("Parameter 'ncenters' must be specified.")
  )
  expect_error(
    WeatherRegime(data = data1$data, ncenters = 3),
    paste0("Parameter 'lon' must be specified.")
  )
  expect_error(
    WeatherRegime(data = data1$data, lon = data1$coords$lon, ncenters = 3),
    paste0("Parameter 'lat' must be specified.")
  )
})

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

test_that("2. Output checks", {
  expect_equal(
    names(dim(CST_WeatherRegimes(data = data1, ncenters = 3, EOFs = FALSE)$data)), 
    c('lat', 'lon', 'cluster')
  )
  data1 <- 1 : 400
  dim(data1) <- c(sdate = 2, ftime = 10, lat = 5, lon = 4)
  data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  nclusters <- 3
  suppressWarnings(
    expect_equal(
      dim(CST_WeatherRegimes(data = data1 ,
                            ncenters = nclusters,
                            EOFs = FALSE)$statistics$frequency), 
      c(2, nclusters)
    )
  )
  suppressWarnings(
    expect_equal(
      names(dim(CST_WeatherRegimes(data = data1, nclusters, EOFs = FALSE)$data)), 
      c('lat', 'lon', 'cluster')
    )
  )
  data1 <- 1 : 400
  dim(data1) <- c(sdate = 2, ftime = 10, lat = 5, lon = 4)
  data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  expect_equal(
    names(CST_WeatherRegimes(data = data1 , ncenters = 4)$statistics),
    c('pvalue', 'cluster', 'frequency', 'persistence')
  )
  expect_equal(
    names(CST_WeatherRegimes(data = data1 , ncenters = 4, method = 'ward.D')$statistics),
    c('pvalue', 'cluster'))
  
  expect_equal(
    names(dim(CST_WeatherRegimes(data = data1, ncenters = 4)$data)), 
    c('lat', 'lon', 'cluster'))
  
  data1 <- 1 : 400
  dim(data1) <- c(time = 20, lat = 5, lon = 4)
  data1[4, , ] <- NA
  data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  expect_error(
    CST_WeatherRegimes(data = data1, ncenters = 3, EOFs = FALSE),
    paste0("Parameter 'data' contains NAs in the 'time' dimensions.")
  )  
  data1 <- 1 : 400
  dim(data1) <- c(time = 20, lat = 5, lon = 4)
  data1[, 2, 3] <- NA
  data1 <- list(data = data1, coords = list(lat = 1:5, lon = 1:4))
  class(data1) <- 's2dv_cube'
  expect_equal(
    any(is.na(CST_WeatherRegimes(data = data1, ncenters = 3, EOFs = FALSE)$data)),
    TRUE
  )
  expect_equal(
    names(dim(CST_WeatherRegimes(data = data1, ncenters = 3, EOFs = FALSE)$data)), 
    c('lat', 'lon', 'cluster')
  )
})


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


