context("s2dv::EuroAtlanticTC tests")

##############################################
  # dat1
  set.seed(1)
  dat1 <- array(rnorm(480), dim = c(sdate = 10, lat = 6, lon = 8))
  lat1 <- seq(20, 80, length.out = 6)
  lon1 <- seq(-90, 60, length.out = 8)

  # dat2
  set.seed(2)
  dat2 <- array(rnorm(800), dim = c(dat = 2, lat = 8, lon = 15, sdate = 5))
  lat2 <- seq(10, 90, length.out = 8)
  lon2 <- seq(-100, 70, length.out = 15)

  # dat3
  set.seed(2)
  dat3 <- array(rnorm(1520), dim = c(dat = 2, lat = 8, lon = 19, sdate = 5))
  lat3 <- seq(10, 90, length.out = 8)
  lon3 <- c(seq(0, 70, length.out = 8), seq(250, 350, length.out = 11))

##############################################
test_that("1. Input checks", {

  # ano
  expect_error(
  EuroAtlanticTC(c()),
  "Parameter 'ano' cannot be NULL."
  )
  expect_error(
    EuroAtlanticTC(c(NA, NA)),
    "Parameter 'ano' must be a numeric array."
  )
  expect_error(
    EuroAtlanticTC(list(a = array(rnorm(50), dim = c(dat = 5, sdate = 10)), b = c(1:4))),
    "Parameter 'ano' must be a numeric array."
  )
  expect_error(
    EuroAtlanticTC(array(1:10, dim = c(2, 5))),
    "Parameter 'ano' must have dimension names."
  )
  # time_dim
  expect_error(
    EuroAtlanticTC(dat1, time_dim = 2),
    "Parameter 'time_dim' must be a character string."
  )
  expect_error(
    EuroAtlanticTC(dat1, time_dim = c('a','sdate')),
    "Parameter 'time_dim' must be a character string."
  )
  # space_dim
  expect_error(
    EuroAtlanticTC(dat1, space_dim = 'lat'),
    "Parameter 'space_dim' must be a character vector of 2."
  )
  expect_error(
    EuroAtlanticTC(dat1, space_dim = c('latitude', 'longitude')),
    "Parameter 'space_dim' is not found in 'ano' dimension."
  )
  # lat and lon
  expect_error(
    EuroAtlanticTC(dat1, lat = 1:10),
    paste0("Parameter 'lat' must be a numeric vector with the same ",
                "length as the latitude dimension of 'ano'.")
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = seq(-100, -80, length.out = 6)),
    "Parameter 'lat' must contain values within the range \\[-90, 90\\]."
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = c('a', 'b')),
    paste0("Parameter 'lon' must be a numeric vector with the same ",
                "length as the longitude dimension of 'ano'.")
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = seq(300, 370, length.out = 8)),
    "Parameter 'lon' must be within the range [-180, 180] or [0, 360].",
    fixed = TRUE
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = seq(-190, -10, length.out = 8)),
    "Parameter 'lon' must be within the range [-180, 180] or [0, 360].",
    fixed = TRUE
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = seq(30, 80, length.out = 6), lon = lon1),
    "The provided data does not cover the EuroAtlantic region (20N-80N, 90W-60E).",
    fixed = TRUE
  )
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = seq(-80, 20, length.out = 8)),
    "The provided data does not cover the EuroAtlantic region (20N-80N, 90W-60E).",
    fixed = TRUE
  )
  # ntrunc
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = lon1, ntrunc = 0),
    "Parameter 'ntrunc' must be a positive integer."
  )
  # corr
  expect_error(
    EuroAtlanticTC(dat1, lat = lat1, lon = lon1, corr = 0.1),
    "Parameter 'corr' must be one logical value."
  )
  # ncores
  expect_error(
    EuroAtlanticTC(dat1, lat1, lon1, ncore = 3.5),
    "Parameter 'ncores' must be a positive integer."
  )

})

##############################################
test_that("2. dat1", {

  expect_equal(
  names(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 4)),
  c("patterns", "indices", "var", "wght")
  )
  expect_equal(
  dim(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 4)$patterns),
  c(mode = 4, lat = 6, lon = 8)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$patterns),
  c(mode = 4, lat = 6, lon = 8)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 9)$indices),
  c(sdate = 10, mode = 4)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$var),
  c(mode = 10)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 4)$wght),
  c(lat = 6, lon = 8)
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 4)$patterns[, 2, 3],
  c(-0.019905033, -0.048926441, -0.330219176, 0.008138493),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 5)$patterns[, 2, 3],
  c(0.01878324, -0.03784923, -0.22820514, -0.21184373),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$indices[2, ],
  c(-1.944509, -1.335159, 0.997195, -2.697545),
  tolerance = 0.0001
  )
  expect_equal(
  mean(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$var),
  10,
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$var[1:4]),
  c(17.995853, 10.768974, 9.598904, 10.234672),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$wght[1,1],
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$wght[1,2]
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 10)$wght[1,1],
  c(0.9693774),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat1, lon = lon1, lat = lat1, ntrunc = 4, corr = T)$patterns[, 2, 3],
  c(-0.05850999, 0.03827591, -0.04454523, -0.43713946),
  tolerance = 0.0001
  )
})

##############################################
test_that("3. dat2", {

  expect_equal(
  names(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 4)),
  c("patterns", "indices", "var", "wght")
  )
  expect_equal(
  dim(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$patterns),
  c(mode = 4, lat = 6, lon = 13, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 4)$patterns),
  c(mode = 4, lat = 6, lon = 13, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$indices),
  c(sdate = 5, mode = 4, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$var),
  c(mode = 5, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 4)$wght),
  c(lat = 6, lon = 13)
  )
  expect_equal(
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 4)$patterns[, 2, 3, 2],
  c(-0.17289486, -0.07021256, -0.08045222, 0.17330862),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$patterns[, 2, 3, 1],
  c(0.1347727, 0.2157945, -0.1024759, 0.1633547),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$indices[2, , 1],
  c(2.1975962, 2.9158790, -3.2257169, -0.4055974),
  tolerance = 0.0001
  )
  expect_equal(
  mean(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$var),
  20,
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$var[1:4]),
  c(23.06692, 21.98278, 20.22588, 19.51251),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$wght[1,1],
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$wght[1,2]
  )
  expect_equal(
  EuroAtlanticTC(dat2, lon = lon2, lat = lat2, ntrunc = 5)$wght[1,1],
  c(0.964818),
  tolerance = 0.0001
  )

})

##############################################
test_that("4. dat3", {

  expect_equal(
  names(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 4)),
  c("patterns", "indices", "var", "wght")
  )
  expect_equal(
  dim(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$patterns),
  c(mode = 4, lat = 6, lon = 16, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 4)$patterns),
  c(mode = 4, lat = 6, lon = 16, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$indices),
  c(sdate = 5, mode = 4, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$var),
  c(mode = 5, dat = 2)
  )
  expect_equal(
  dim(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 4)$wght),
  c(lat = 6, lon = 16)
  )
  expect_equal(
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 4)$patterns[, 2, 3, 2],
  c(-0.10653582, -0.22437848, 0.10192633, 0.08331549),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$patterns[, 2, 3, 1],
  c(0.25209479, -0.05872688, 0.03186457, -0.02901076),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$indices[2, , 1],
  c(2.940060, 5.036896, 4.188896, 2.816158),
  tolerance = 0.0001
  )
  expect_equal(
  mean(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$var),
  20,
  tolerance = 0.0001
  )
  expect_equal(
  as.vector(EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$var[1:4]),
  c(24.38583, 22.57439, 20.19659, 17.95064),
  tolerance = 0.0001
  )
  expect_equal(
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$wght[1,1],
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$wght[1,2]
  )
  expect_equal(
  EuroAtlanticTC(dat3, lon = lon3, lat = lat3, ntrunc = 5)$wght[1,1],
  c(0.964818),
  tolerance = 0.0001
  )

})

