##############################################
library(startR)
library(s2dv)
##############################################

test_that("1. Input checks", {
  expect_error(
    as.s2dv_cube(object = array(1:10, dim = c(sdate = 2, lat = 5))),
    paste0("The class of parameter 'object' is not implemented",
           " to be converted into 's2dv_cube' class yet.")
  )
  expect_error(
    as.s2dv_cube(object = as.list(1:11)),
    paste0("The s2dv::Load call did not return any data.")
  )
})

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

# test_that("2. Tests from Load()", {
#   startDates <- c('20001101', '20011101')
#   suppressWarnings(
#     ob1 <- Load(var = 'tas', exp = 'system5c3s',
#                 nmember = 2, sdates = startDates,
#                 leadtimemax = 3, latmin = 30, latmax = 35,
#                 lonmin = 10, lonmax = 20, output = 'lonlat')
#   )
#   res1 <- as.s2dv_cube(ob1)

#   # dimensions
#   expect_equal(
#     dim(res1$data),
#     c(dataset = 1, member = 2, sdate = 2, ftime = 3, lat = 6, lon = 11)
#   )
#   # elements
#   expect_equal(
#     names(res1),
#     c("data", "dims", "coords", "attrs")
#   )
#   expect_equal(
#     names(res1$attrs),
#     c("Variable", "Datasets", "Dates", "when", "source_files", 
#       "not_found_files", "load_parameters")
#   )
#   # coordinates
#   expect_equal(
#     attributes(res1$coords$sdate),
#     list(indices = FALSE)
#   )
#   expect_equal(
#     attributes(res1$coords$ftime),
#     list(indices = TRUE)
#   )
#   expect_equal(
#     dim(res1$coords$lat), 
#     NULL
#   )
#   expect_equal(
#     dim(res1$coords$lon),
#     NULL
#   )
#   expect_equal(
#     length(res1$coords$lat),
#     6
#   )
#   # Dates
#   expect_equal(
#     dim(res1$attrs$Dates),
#     c(ftime = 3, sdate = 2)
#   )
# })

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

# test_that("3. Tests from Load()", {
#   obs_path <- list(name = "ERA5",
#                   path = "/esarchive/recon/ecmwf/era5/$STORE_FREQ$_mean/$VAR_NAME$_f1h/$VAR_NAME$_$YEAR$$MONTH$.nc")
#   ob2 <- Load(var = 'windagl100', obs = list(obs_path),
#               sdates = '20180301', nmember = 1,
#               leadtimemin = 1, leadtimemax = 1,
#               storefreq = "monthly", sampleperiod = 1,
#               latmin = 36, latmax = 38, lonmin = 0, lonmax = 4,
#               output = 'lonlat', nprocs = 1, grid = 'r360x181')

#   res2 <- as.s2dv_cube(ob2)

#   # dimensions
#   expect_equal(
#     dim(res2$data),
#     c(dataset = 1, member = 1, sdate = 1, ftime = 1, lat = 3, lon = 5)
#   )
#   # elements
#   expect_equal(
#     names(res2$attrs),
#     c("Variable", "Datasets", "Dates", "when", "source_files", 
#       "not_found_files", "load_parameters")
#   )
#   # coordinates
#   expect_equal(
#     attributes(res2$coords$sdate),
#     list(indices = FALSE)
#   )
#   expect_equal(
#     unlist(res2$coords)[1:4],
#     c(dataset = "ERA5", member = "1", sdate = "20180301", ftime = "1")
#   )
#   expect_equal(
#     dim(res2$coords$ftime), 
#     NULL
#   )
#   expect_equal(
#     length(res2$coords$lat),
#     3
#   )
#   # Dates
#   expect_equal(
#     dim(res2$attrs$Dates),
#     c(ftime = 1, sdate = 1)
#   )
# })

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

# test_that("4. Tests from Load()", {
#   exp <- list(name = 'ecmwfS5',
#               path = "/esarchive/exp/ecmwf/system5c3s/$STORE_FREQ$_mean/$VAR_NAME$_s0-24h/$VAR_NAME$_$START_DATE$.nc")
#   obs <- list(name = 'era5',
#               path = '/esarchive/recon/ecmwf/era5/$STORE_FREQ$_mean/$VAR_NAME$_f1h-r1440x721cds/$VAR_NAME$_$YEAR$$MONTH$.nc')
#   suppressWarnings(
#     ob3 <- Load(var = 'prlr', exp = list(exp), obs = list(obs),
#                 sdates = paste0(1993:1995, '1101'), nmember = 1,
#                 storefreq = "monthly", sampleperiod = 1,
#                 latmin = 42, latmax = 45, lonmin = 4, lonmax = 6,
#                 output = 'lonlat', nprocs = 1)
#   )
#   expect_warning(
#     as.s2dv_cube(ob3),
#     "The output is a list of two 's2dv_cube' objects corresponding to 'exp' and 'obs'."
#   )
#   suppressWarnings(
#     res3 <- as.s2dv_cube(ob3)
#   )

#   # dimensions
#   expect_equal(
#     dim(res3[[1]]$data),
#     c(dataset = 1, member = 1, sdate = 3, ftime = 8, lat = 4, lon = 3)
#   )
#   expect_equal(
#     unlist(res3[[1]]$coords)[1:4],
#     c(dataset = "ecmwfS5", member = "1", sdate1 = "19931101", sdate2 = "19941101")
#   )
#   # Dates
#   expect_equal(
#     dim(res3[[1]]$attrs$Dates),
#     dim(res3[[2]]$attrs$Dates)
#   )
# })

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

test_that("5. Tests from Start()", {
  repos <- '/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc'
  suppressWarnings(
    data1 <- Start(dat = repos,
                   var = 'tas',
                   sdate = c('20170101', '20180101'),
                   ensemble = indices(1:3),
                   time = indices(1:3),
                   latitude = indices(1:2),
                   longitude = indices(1:2),
                   return_vars = list(latitude = 'dat', longitude = 'dat', time = 'sdate'),
                   retrieve = TRUE)
  )

  res4 <- as.s2dv_cube(data1)

  # dimensions
  expect_equal(
    dim(res4$data),
    c(dat = 1, var = 1, sdate = 2, ensemble = 3, time = 3, latitude = 2, longitude = 2)
  )
  # elements
  expect_equal(
    names(res4),
    c("data", "dims", "coords", "attrs")
  )
  expect_equal(
    names(res4$attrs),
    c("Dates", "Variable", "Datasets", "when", "source_files", "load_parameters")
  )
  # coordinates
  expect_equal(
    names(res4$coords),
    c("dat", "var", "sdate", "ensemble", "time", "latitude", "longitude")
  )
  expect_equal(
    dim(res4$coords$dat),
    NULL
  )
  expect_equal(
    dim(res4$coords$latitude),
    NULL
  )
  expect_equal(
    length(res4$coords$latitude), 
    2
  )
  # Dates
  expect_equal(
    dim(res4$attrs$Dates),
    c(sdate = 2, time = 3)
  )
})

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

test_that("6. Tests from Start()", {
  vari <- "rsds"
  anlgs <- paste0("/esarchive/oper/VITIGEOSS","/output/cfsv2/weekly_mean/",
                  "$var$/$var$-vitigeoss-cat","_1999-2018_", "$file_date$.nc")

  file_date_array <- array(dim = c(sweek = 2, sday = 3))
  file_date_array[, 1] <- c(paste0('04', c('04', '07')))
  file_date_array[, 2] <- c(paste0('04', c('07', '11')))
  file_date_array[, 3] <- c(paste0('04', c('11', '14')))

  suppressWarnings(
    hcst <- Start(dat = anlgs,
                  var = vari,
                  latitude = indices(1:2), #'all', 
                  longitude = indices(1:2), #'all', 
                  member = indices(1), #'all', 
                  time = indices(1:3),
                  syear = indices(1:4),
                  file_date = file_date_array,
                  split_multiselected_dims = TRUE,
                  retrieve = T,
                  return_vars = list(leadtimes = 'file_date', longitude = 'dat', latitude = 'dat'),
                  synonims = list(longitude = c('lon', 'longitude'),
                                  latitude = c('lat', 'latitude'),
                                  syear = c('sdate','syear'),
                                  member = c('ensemble','member')))
  )

  res5 <- as.s2dv_cube(hcst)

  # dimensions
  expect_equal(
    dim(res5$data),
    c(dat = 1, var = 1, latitude = 2, longitude = 2, member = 1, time = 3, 
      syear = 4, sweek = 2, sday = 3)
  )
  # elements
  expect_equal(
    names(res5),
    c("data", "dims", "coords", "attrs")
  )
  expect_equal(
    names(res5$attrs),
    c("Variable", "Dates", "Datasets", "when", "source_files", "load_parameters")
  )
  # coordinates
  expect_equal(
    names(res5$coords),
    c('dat', 'var', 'latitude', 'longitude', 'member', 'time', 'syear', 'sweek', 'sday')
  )
  expect_equal(
    dim(res5$coords$longitude),
    NULL
  )
  # Dates
  expect_equal(
    dim(res5$attrs$Dates),
    c(sweek = 2, sday = 3, syear = 20, time = 4)
  )
})

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

test_that("7. Tests from Start()", {
  repos <- "/esarchive/exp/ecmwf/system5_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc"
  repos2 <- "/esarchive/exp/ecmwf/system4_m1/monthly_mean/$var$_f6h/$var$_$sdate$.nc"

  suppressWarnings(
    data6 <- Start(dat = list(list(name = 'system4_m1', path = repos2),
                              list(name = 'system5_m1', path = repos)),
                  var = c('tas', 'sfcWind'),
                  sdate = '20170101',
                  ensemble = indices(1),
                  time = indices(1),
                  lat = indices(1:5),
                  lon = indices(1:5),
                  synonims = list(lat = c('lat', 'latitude'),
                                  lon = c('lon', 'longitude')),
                  return_vars = list(time = 'sdate',
                                      longitude = 'dat',
                                      latitude = 'dat'),
                  metadata_dims = c('dat', 'var'),
                  retrieve = T)
  )

  suppressWarnings(
    res6 <- as.s2dv_cube(data6)
  )
  
  # dimensions
  expect_equal(
    dim(res6$data),
    c(dat = 2, var = 2, sdate = 1, ensemble = 1, time = 1, lat = 5, lon = 5)
  )
  # elements
  expect_equal(
    names(res6),
    c("data", "dims", "coords", "attrs")
  )
  expect_equal(
    res6$attrs$Variable$varName,
    c('tas', 'sfcWind')
  )
  # coordinates
  expect_equal(
    names(res6$coords),
    c('dat', 'var', 'sdate', 'ensemble', 'time', 'lat', 'lon')
  )
  # Dates
  expect_equal(
    dim(res6$attrs$Dates),
    c(sdate = 1, time = 1)
  )
})

##############################################
# commented as 'path' not available
# test_that("8. Tests from Start()", {
#   path <- paste0('/esarchive/exp/ecearth/a3t4/diags/CMIP/EC-Earth-Consortium/EC-Earth3-LR/piControl/$memb$/Omon/$var$/gn/',
#                  'v*/$var$_Omon_EC-Earth3-LR_piControl_$memb$_gn_$chunk$.nc')
#   suppressWarnings(
#       data7 <- Start(dat = list(list(name = 'a3t4', path = path)),
#                  var = 'tosmean',
#                  memb = paste0('r', 1:5, 'i1p1f1'),
#                  region = c("ATL3", "Global_Ocean", "Nino3.4"),
#                  time = indices(1:10),
#                  chunk = 'all',
#                  time_across = 'chunk',
#                  merge_across_dims = TRUE,
#                  return_vars = list(time = 'chunk', region = NULL),
#                  num_procs = 8,
#                  retrieve = T)
#   )
# 
#   res7 <- as.s2dv_cube(data7)
#   
#   # dimensions
#   expect_equal(
#     dim(res7$data),
#     c(dat = 1, var = 1, memb = 5, region = 3, time = 10)
#   )
#   # elements
#   expect_equal(
#     names(res7),
#     c("data", "dims", "coords", "attrs")
#   )
#   expect_equal(
#     res7$attrs$Variable$varName,
#     c('tosmean')
#   )
#   # Dates
#   expect_equal(
#     dim(res7$attrs$Dates),
#     c(time = 10)
#   )
# })

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