context("Generic tests")
test_that("Sanity and Functionality tests", {
  data <- rnorm(2 * 15 * 4 * 5 * 6 * 7)
  dim(data) <- c(dataset = 2, member = 15,
                 sdate = 4, ftime = 5, lat = 6, lon = 7)
  lon <- seq(0, 12, 2)
  lat <- seq(10, 15, 1)
  exp <- list(data = data, lat = lat, lon = lon)

  # Check error messages
  expect_error(
    CST_EnsClustering(exp),
    "Parameter 'exp' must be of the class 's2dv_cube'"
  )
  attr(exp, "class") <- "s2dv_cube"

  expect_error(
    CST_EnsClustering(exp, time_moment = "invalid"),
    "Invalid time_moment"
  )

  exp$lat <- 1
  expect_error(CST_EnsClustering(exp), "Incorrect lat length")
  exp$lon <- 1
  exp$lat <- lat
  expect_error(CST_EnsClustering(exp), "Incorrect lon length")
  exp$lon <- lon

  # Sanity checks on dimensions
  res <- CST_EnsClustering(exp, numclus = 3)
  expect_equivalent(dim(res$cluster), dim(exp$data)[c(2, 1, 3)])
  res <- CST_EnsClustering(exp, numclus = 3, cluster_dim = "sdate")
  expect_equivalent(dim(res$cluster), dim(exp$data)[c(3, 1, 2)])
  res <- CST_EnsClustering(exp, numclus = 3,
                     cluster_dim = c("member", "dataset", "sdate"))
  expect_equivalent(dim(res$cluster), dim(exp$data)[c(2, 1, 3)])
  res <- CST_EnsClustering(exp, numclus = 3, cluster_dim = c("member", "sdate"))
  expect_equivalent(dim(res$cluster), dim(exp$data)[c(2, 3, 1)])
  expect_equivalent(dim(res$freq), c(cluster = 3, dim(exp$data)[1]))
  expect_equivalent(dim(res$closest_member), c(cluster = 3, dim(exp$data)[1]))
  expect_equivalent(dim(res$repr_field), c(cluster = 3,
                    dim(exp$data)[c(5, 6)], dim(exp$data)[1]))
  expect_equivalent(dim(res$composites), c(cluster = 3,
                    dim(exp$data)[c(5, 6)], dim(exp$data)[1]))

  # Functionality tests
  res <- CST_EnsClustering(exp, numclus = 3, variance_explained = 80,
                     cluster_dim = "member")
  # The closest member of each cluster should be member of that cluster
  for (i in 1:3) {
    expect_equivalent(res$cluster[res$closest_member[i, 1, 1], 1, 1], i)
  }

  res <- CST_EnsClustering(exp, numclus = 3, numpcs = 8,
                     cluster_dim = c("member"))
  for (i in 1:3) {
    expect_equivalent(res$cluster[res$closest_member[i, 1, 1], 1, 1], i)
  }

  res <- CST_EnsClustering(exp, numclus = 3, variance_explained = 80,
                     cluster_dim = c("member"))

  # The weighted mean of all cluster mean fields should be 0
  comp1 <- sweep(res$composites, c(1, 4, 5), res$freq / 100, "*")
  cmean <- apply(comp1, c(2, 3, 4, 5), mean)[ , , 1, 1]
  expect_equal(mean(cmean), 0., tolerance = 1e-10)

  # This should give a different result
  res2 <- CST_EnsClustering(exp, numclus = 3, variance_explained = 80,
                      cluster_dim = c("member"),
                      lat_lim = c(10, 12), lon_lim = c(0, 6))
  expect_gt(sum((res$cluster - res2$cluster)^2), 0)
})
