context("CSTools::CST_SaveExp tests")
##############################################

# cube0
cube0 <- array(1:5, dim = c(sdate = 5, lon = 4, lat = 4, ftime = 1))
class(cube0) <- 's2dv_cube'

# cube1
cube1 <- NULL
cube1$data <- array(1:5, dim = c(sdate = 5, lon = 4, lat = 4, ftime = 1))
coords2 <- list(sdate = c('20000101', '20010102', '20020103', '20030104', '20040105'), 
                var = 'tas',
                lon = 1.:4., 
                lat = 1.:4.)
cube1$coords <- coords2
dates2 <- c('20000101', '20010102', '20020103', '20030104', '20040105')
dates2 <- as.Date(dates2, format = "%Y%m%d", tz = "UTC")
dim(dates2) <- c(sdate = 5, ftime = 1)
cube1$attrs$Dates <- dates2
class(cube1) <- 's2dv_cube'

# cube2
cube2 <- cube1
cube2$data <- array(1:5, dim = c(sdate = 5, lon = 4, lat = 4, ftime = 1, 
                                 test = 2, test2 = 3))
dim(cube2$data) <- c(sdate = 5, lon = 4, lat = 4, ftime = 1, member = 1, 
                     ensemble = 1, test = 2, test2 = 3)

# cube3
cube3 <- cube1

# dat0
dates0 <- as.Date('2022-02-01', format = "%Y-%m-%d")
dim(dates0) <- c(sdate = 1)
# dat1
dat1 <- array(1, dim = c(test = 1))
# dat2
dat2 <- array(1:5, dim = c(sdate = 5, lon = 4, lat = 4, ftime = 1))
coords2 <- list(sdate = c('20000101', '20010102', '20020103', '20030104', '20040105'), 
                var = 'tas',
                lon = 1.:4., 
                lat = 1.:4.)
dates2 <- c('20000101', '20010102', '20020103', '20030104', '20040105')
dates2 <- as.Date(dates2, format = "%Y%m%d", tz = "UTC")
dim(dates2) <- c(sdate = 5, ftime = 1)

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

test_that("1. Input checks: CST_SaveExp", {
  # s2dv_cube
  expect_error(
    CST_SaveExp(data = 1), 
    paste0("Parameter 'data' must be of the class 's2dv_cube', ",
           "as output by CSTools::CST_Load.")
  )
  # structure
  expect_error(
    CST_SaveExp(data = cube0), 
    paste0("Parameter 'data' must have at least 'data' and 'attrs' elements ",
           "within the 's2dv_cube' structure.")
  )
  cube0 <- list(data = cube0, attrs = 1)
  class(cube0) <- 's2dv_cube'
  expect_error(
    CST_SaveExp(data = cube0), 
    paste0("Level 'attrs' must be a list with at least 'Dates' element.")
  )
  # cube0$attrs <- NULL
  # cube0$attrs$Dates <- dates2
  # expect_warning(
  #   CST_SaveExp(data = cube0, sdate_dim = c('sdate', 'sweek'), 
  #               ftime_dim = 'ftime', memb_dim = NULL, dat_dim = NULL,
  #               var_dim = NULL, single_file = FALSE), 
  #   paste0("Element 'coords' not found. No coordinates will be used.")
  # )

  # sdate_dim
  suppressWarnings(
    expect_error(
      CST_SaveExp(data = cube1, sdate_dim = 1), 
      paste0("Parameter 'sdate_dim' must be a character string.")
    )
  )
  # expect_warning(
  #   CST_SaveExp(data = cube1, sdate_dim = c('sdate', 'sweek'), 
  #               ftime_dim = 'ftime', memb_dim = NULL, dat_dim = NULL,
  #               var_dim = NULL), 
  #   paste0("Parameter 'sdate_dim' has length greater than 1 and ",
  #          "only the first element will be used.")
  # )
  suppressWarnings(
    expect_error(
      CST_SaveExp(data = cube1, sdate_dim = 'a', ftime_dim = 'ftime'), 
      paste0("Parameter 'sdate_dim' is not found in 'data' dimension.")
    )
  )
  # # metadata
  # expect_warning(
  #   CST_SaveExp(data = cube1, ftime_dim = 'ftime', memb_dim = NULL, 
  #               dat_dim = NULL, var_dim = NULL), 
  #   paste0("No metadata found in element Variable from attrs.")
  # )
  cube1$attrs$Variable$metadata <- 'metadata'
  expect_error(
    CST_SaveExp(data = cube1, ftime_dim = 'ftime', memb_dim = NULL, 
                dat_dim = NULL, var_dim = NULL), 
    paste0("Element metadata from Variable element in attrs must be a list.")
  )
  cube1$attrs$Variable$metadata <- list(test = 'var')
  # expect_warning(
  #   CST_SaveExp(data = cube1, ftime_dim = 'ftime', memb_dim = NULL, 
  #               dat_dim = NULL, var_dim = NULL), 
  #   paste0("Metadata is not found for any coordinate.")
  # )
  cube1$attrs$Variable$metadata <- list(var = 'var')
  # expect_warning(
  #   CST_SaveExp(data = cube1, ftime_dim = 'ftime', memb_dim = NULL, 
  #               dat_dim = NULL, var_dim = NULL), 
  #   paste0("Metadata is not found for any variable.")
  # )
  # memb_dim
  suppressWarnings(
    expect_error(
      CST_SaveExp(data = cube1, memb_dim = 1, ftime_dim = 'ftime'), 
      paste0("Parameter 'memb_dim' must be a character string.")
    )
  )
  suppressWarnings(
    expect_error(
      CST_SaveExp(data = cube1, memb_dim = 'member', ftime_dim = 'ftime'), 
      paste0("Parameter 'memb_dim' is not found in 'data' dimension. Set it ", 
             "as NULL if there is no member dimension.")
    )
  )
  # expect_warning(
  #   CST_SaveExp(data = cube2, memb_dim = c('member', 'ensemble'), 
  #               ftime_dim = 'ftime', dat_dim = NULL, var_dim = NULL), 
  #   paste0("Detected unknown dimension: test, test2")
  # )
})

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

test_that("1. Input checks", {
  # data
  expect_error(
    SaveExp(data = NULL),
    "Parameter 'data' cannot be NULL."
  )
  expect_error(
    SaveExp(data = 1:10),
    "Parameter 'data' must be an array with named dimensions."
  )
  # destination
  expect_error(
    SaveExp(data = array(1, dim = c(a = 1)), destination = NULL),
    paste0("Parameter 'destination' must be a character string of one element ",
           "indicating the name of the file (including the folder if needed) ",
           "where the data will be saved."), 
    fixed = TRUE
  )
  # Dates
  expect_error(
    SaveExp(data = array(1, dim = c(a = 1)), Dates = 'a'),
    paste0("Parameter 'Dates' must be of 'POSIXct' or 'Dates' class.")
  )
  expect_error(
    SaveExp(data = array(1, dim = c(a = 1)), 
            Dates = as.Date('2022-02-01', format = "%Y-%m-%d")),
    paste0("Parameter 'Dates' must have dimension names.")
  )
  # # varname
  # expect_warning(
  #   SaveExp(data = dat2, coords = coords2, 
  #           metadata = list(tas = list(level = '2m')),
  #           Dates = dates2, ftime_dim = 'ftime', memb_dim = NULL, 
  #           dat_dim = NULL, var_dim = NULL),
  #   paste0("Parameter 'varname' is NULL. It will be assigned to 'X'.")
  # )
  suppressWarnings(
    expect_error(
      SaveExp(data = dat2, coords = coords2, varname = 1, 
                metadata = list(tas = list(level = '2m')),
                Dates = dates2),
      "Parameter 'varname' must be a character."
    )
  )
  # # coords
  # expect_warning(
  #   SaveExp(data = dat2, coords = list(sdate = coords2[[1]]), 
  #           varname = 'tas', metadata = list(tas = list(level = '2m')),
  #           Dates = dates2, ftime_dim = 'ftime', memb_dim = NULL, 
  #           dat_dim = NULL, var_dim = NULL),
  #   "Coordinate 'lon' is not provided and it will be set as index in element coords.",
  #   "Coordinate 'lat' is not provided and it will be set as index in element coords.",
  #   "Coordinate 'ftime' is not provided and it will be set as index in element coords."
  # )
  # # varname, metadata, spatial coords, unknown dim
  # expect_warning(
  #   SaveExp(data = dat1, ftime_dim = NULL, sdate_dim = NULL, memb_dim = NULL, 
  #           dat_dim = NULL, var_dim = NULL, single_file = TRUE),
  #   "Parameter 'varname' is NULL. It will be assigned to 'X'.",
  #   "Parameter 'metadata' is not provided so the metadata saved will be incomplete.",
  #   paste0("Parameter 'single_file' is TRUE. Time values saved in the NetCDF ", 
  #           "file may not be consistent for all the start dates. ", 
  #           "Further development of the function is needed, sorry ", 
  #           "for the inconvinience."),
  #   paste0("Spatial coordinate names do not match any of the names accepted by ",
  #          "the package."),
  #   "Detected unknown dimension: test"
  # )
  expect_error(
    SaveExp(data = dat1, varname = 1, ftime_dim = NULL, sdate_dim = NULL,  
            memb_dim = NULL, dat_dim = NULL, var_dim = NULL),
    paste0("Parameter 'varname' must be a character string with the ",
           "variable names.")
  )
})

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