context("multiStart() NA insertion")
# Same case as ex2_12.
#---------------------------------------------------------------

variable <- 'tas'
sdates <- 2000:2004

## Paths
path_hadgem3 <- paste0('/esarchive/exp/CMIP6/dcppA-hindcast/hadgem3-gc31-mm/cmip6-dcppA-hindcast_i1p1/DCPP/',
                       'MOHC/HadGEM3-GC31-MM/dcppA-hindcast/r1i1p1f2/Amon/$var$/gr/v20200316/',
                       '$var$_*_s$sdate$_r1i1p1f2_gr_$fyear$.nc')
path_ipsl <- paste0('/esarchive/exp/CMIP6/dcppA-hindcast/ipsl-cm6a-lr/cmip6-dcppA-hindcast_i1p1/DCPP/',
                    'IPSL/IPSL-CM6A-LR/dcppA-hindcast/r1i1p1f1/Amon/$var$/gr/v20200504/',
                    '$var$_Amon_IPSL-CM6A-LR_dcppA-hindcast_s$sdate$-r1i1p1f1_gr_$fyear$.nc')
path_norcpm1 <- paste0('/esarchive/exp/CMIP6/dcppA-hindcast/norcpm1/cmip6-dcppA-hindcast_i1p1/DCPP/',
                       'NCC/NorCPM1/dcppA-hindcast/r1i1p1f1/Amon/$var$/gn/v20200320/',
                       '$var$_Amon_NorCPM1_dcppA-hindcast_s$sdate$-r1i1p1f1_gn_$fyear$.nc')

## Forecast months: six indices (from October to March)
time_hadgem3 <- indices(c(NA, 1, 2, 3, 4, 5))
time_ipsl <- indices(c(NA, NA, NA, 1, 2, 3))
time_norcpm1 <- indices(c(1, 2, 3, 4, 5, 6))


test_that("1. retrieve = T", {

suppressWarnings(
data <- multiStart(dat = list(list(name = 'hadgem3', path = path_hadgem3),
                              list(name = 'ipsl', path = path_ipsl),
                              list(name = 'norcpm1', path = path_norcpm1)),
                   var = variable,
                   sdate = paste0(sdates),
                   fyear = indices(1), ## there is one file per sdate
                   fyear_depends = 'sdate',
                   time = list(list(name = 'hadgem3', time = time_hadgem3),
                               list(name = 'ipsl', time = time_ipsl),
                               list(name = 'norcpm1', time = time_norcpm1)),
                   lat = values(list(-30, 30)),
                   lon = values(list(0, 50)),
                   synonims = list(lon = c('lon', 'longitude'), lat = c('lat', 'latitude')),
                   transform = CDORemapper,
                   transform_params = list(grid = 'r180x90',
                                           method = 'conservative',
                                           crop = c(0, 50, -30, 30)),
                   transform_vars = c('lat', 'lon'),
                   return_vars = list(lat = NULL, lon = NULL, time = 'sdate'),
                   retrieve = TRUE)
)


expect_equal(
dim(data),
c(dat = 3, var = 1, sdate = 5, fyear = 1, time = 6, lat = 30, lon = 26)
)
expect_equal(
mean(data, na.rm = T),
295.4626,
tolerance = 0.0001
)
expect_equal(
length(which(is.na(data))),
15600
)
expect_equal(
data[1, 1, 2, 1, 1:4, 1, 1],
c(NA, 290.1964, 292.6637, 293.2186),
tolerance = 0.0001
)
expect_equal(
data[2, 1, 2, 1, 1:4, 1, 1],
c(NA, NA, NA, 294.2315),
tolerance = 0.0001
)
expect_equal(
data[3, 1, 2, 1, 1:4, 1, 1],
c(288.6785, 289.5546, 290.4638, 291.7312),
tolerance = 0.0001
)

})


test_that("2. retrieve = F", {

suppressWarnings(
data <- multiStart(dat = list(list(name = 'hadgem3', path = path_hadgem3),
                              list(name = 'ipsl', path = path_ipsl),
                              list(name = 'norcpm1', path = path_norcpm1)),
                   var = variable,
                   sdate = paste0(sdates),
                   fyear = indices(1), ## there is one file per sdate
                   fyear_depends = 'sdate',
                   time = list(list(name = 'hadgem3', time = time_hadgem3),
                               list(name = 'ipsl', time = time_ipsl),
                               list(name = 'norcpm1', time = time_norcpm1)),
                   lat = values(list(-30, 30)),
                   lon = values(list(0, 50)),
                   synonims = list(lon = c('lon', 'longitude'), lat = c('lat', 'latitude')),
                   transform = CDORemapper,
                   transform_params = list(grid = 'r180x90',
                                           method = 'conservative',
                                           crop = c(0, 50, -30, 30)),
                   transform_vars = c('lat', 'lon'),
                   return_vars = list(lat = NULL, lon = NULL, time = 'sdate'),
                   retrieve = FALSE)
)

expect_equal(
length(data),
3
)
expect_equal(
names(data),
c("hadgem3", "ipsl", "norcpm1")
)

# Therefore, the operation should consider three data arrays 
# rather than one.
fun <- function(dat1, dat2, dat3) {
  # dat: [dat = 1]
  mean(c(dat1, dat2, dat3), na.rm = TRUE)
}

# As explained above, the number of data arrays is three, so the target_dims is a 
# list of three. The names of dataset (i.e., dat1, dat2, dat3) can be random.
step <- Step(fun = fun,
             target_dims = list(dat1 = 'dat', dat2 = 'dat', dat3 = 'dat'),
             output_dims = NULL)

# The inputs is still 'data', which contains three calls implicitly.
wf <- AddStep(inputs = data, step_fun = step)


# run locally
output <- Compute(workflow = wf,
                          chunks = list(sdate = 2))$output1


expect_equal(
dim(output),
c(time = 6, var = 1, sdate = 5, fyear = 1, lat = 30, lon = 26)
)

expect_equal(
mean(output),
295.4511,
tolerance = 0.0001
)
expect_equal(
length(which(is.na(output))),
0
)
expect_equal(
output[1:5],
c(288.9735, 290.6019, 291.8069, 293.3672, 293.4944),
tolerance = 0.0001
)


})
