# data1: regular grid
data1 <- array(1:360*181*2, dim = c(lon = 360, lat = 181, time = 2))
lons1 <- seq(0, 359)
lats1 <- seq(-90, 90)
data1_1 <- .aperm2(data1, c(3, 1, 2))
data1_2 <- InsertDim(data1, 1, 1, name = 'var')
data1_3 <- InsertDim(data1_2, 5, 1, name = 'dat')

# data2: irregular grid
data2 <- readRDS('../testdata/testIrregularGrid_1.rds')
lons2 <- attributes(data2)$Variables$common$nav_lon#[2:361, 2:331]
lats2 <- attributes(data2)$Variables$common$nav_lat#[2:361, 2:331]

data2_1 <- ClimProjDiags::Subset(data2, 1, 1, drop = 'selected')
data2_2 <- ClimProjDiags::Subset(data2, 5, 1, drop = 'selected')
data2_3 <- ClimProjDiags::Subset(data2, c(1, 2), list(1, 1), drop = 'selected')
data2_4 <- ClimProjDiags::Subset(data2, c(1, 2, 5), list(1, 1, 1), drop = 'selected')
data2_5 <- .aperm2(data2, c(3,4,1,2,5))
data2_6 <- .aperm2(data2, c(3,4,5,2,1))
data2_7 <- .aperm2(data2, c(4,3,1,2,5))
data2_8 <- .aperm2(data2_4, c(2,1))

# data3: irregular grid
data3 <- readRDS('../testdata/testIrregularGrid_2.rds')
lons3 <- attributes(data3)$Variables$common$longitude
lats3 <- attributes(data3)$Variables$common$latitude

data3_1 <- drop(data3)
data3_2 <- .aperm2(data3_1, c(2, 1))

# data4: irregular grid
data4 <- readRDS('../testdata/testIrregularGrid_3.rds')
lons4 <- attributes(data4)$Variables$common$longitude
lats4 <- attributes(data4)$Variables$common$latitude

data4_1 <- drop(data4)
data4_2 <- ClimProjDiags::Subset(data4, c(1,2,3,4,8), list(1,1,1,1,1), drop = 'selected')
data4_3 <- .aperm2(data4_2, c(1, 3, 2))

# data5: regular grid, more dimensions  
data5 <- array(1:(4*10*8*3*2), dim = c(dat = 1, var = 1, memb = 4, lon = 10, lat = 8, sdate = 3, sweek = 2))
data5_1 <- aperm(data5, c(1,2,3,6,4,5,7))

# data6: regular grid, latitudes and longitudes in descent order
data6 <- rnorm(3*180*360)
dim(data6) <- c(time = 3, latitude = 180, longitude = 360)
lats6 <- seq(89.5, -89.5, -1)
lons6 <- seq(359.5,0.5,  -1)

# data7: regular grid, crop = T
data7 <- array(1:50, dim = c(25, 50))
names(dim(data7)) <- c('lat', 'lon')
lons7 <- seq(0, 360 - 360/50, length.out = 50)
lats7 <- seq(-90, 90, length.out = 25)

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

test_that("1. Input checks", {

expect_error(
CDORemap(data_array = NULL, lons = 'lons', lats = 'lats'),
"Expected numeric 'lons' and 'lats'."
)
expect_error(
CDORemap(data_array = NULL, lons = c(NA, lons1), lats = lats1),
"Found invalid values in 'lons'."
)
expect_error(
CDORemap(data_array = NULL, lons = lons1, lats = c(NA, lats1)),
"Found invalid values in 'lats'."
)

})

test_that("2. regular regrid", {
suppressWarnings(
res <- CDORemap(data1, lons1, lats1, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res1 <- CDORemap(data1_1, lons1, lats1, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res2 <- CDORemap(data1_2, lons1, lats1, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res3 <- CDORemap(data1_3, lons1, lats1, grid = 'r100x50', method = 'bil', crop = F)$data_array
)

expect_equal(
as.vector(res),
as.vector(.aperm2(res1, c(2,3,1)))
)
expect_equal(
as.vector(res),
as.vector(res2)
)
expect_equal(
as.vector(res),
as.vector(res3)
)

})

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

test_that("3. dat2: irregular regrid", {
suppressWarnings(
res <- CDORemap(data2, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res1 <- CDORemap(data2_1, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res2 <- CDORemap(data2_2, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res3 <- CDORemap(data2_3, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res4 <- CDORemap(data2_4, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res5 <- CDORemap(data2_5, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res6 <- CDORemap(data2_6, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res7 <- CDORemap(data2_7, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res8 <- CDORemap(data2_8, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
# no data
suppressWarnings(
res9 <- CDORemap(NULL, lons2, lats2, grid = 'r100x50', method = 'bil', crop = F)
)

expect_equal(
drop(res)[95:100, 50],
c(99.54009, 99.53733, 99.53453, 99.53169, 99.52792, 99.52304),
tolerance = 0.0001
)
expect_equal(
as.vector(res),
as.vector(res1)
)
expect_equal(
as.vector(res),
as.vector(res2)
)
expect_equal(
as.vector(res),
as.vector(res3)
)
expect_equal(
as.vector(res),
as.vector(res4)
)
expect_equal(
as.vector(res),
as.vector(res5)
)
expect_equal(
as.vector(res),
as.vector(res6)
)
expect_equal(
as.vector(res),
as.vector(res7)
)
expect_equal(
as.vector(res),
as.vector(res8)
)
expect_equal(
res9$data_array,
NULL
)
expect_equal(
as.vector(res9$lons)[1:5],
c(0.0, 3.6, 7.2, 10.8, 14.4)
)
expect_equal(
as.vector(res9$lats)[1:5],
c(-88.2, -84.6, -81.0, -77.4, -73.8)
)

})

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

test_that("4. dat3: irregular regrid", {
suppressWarnings(
res <- CDORemap(data3, lons3, lats3, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res1 <- CDORemap(data3_1, lons3, lats3, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res2 <- CDORemap(data3_2, lons3, lats3, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
# no data
suppressWarnings(
res3 <- CDORemap(NULL, lons3, lats3, grid = 'r100x50', method = 'bil', crop = F)
)

expect_equal(
as.vector(res),
as.vector(res1)
)
expect_equal(
as.vector(res),
as.vector(res2)
)
expect_equal(
res1[1:5, 50],
c(-1.588068, -1.586225, -1.584405, -1.582579, -1.580713),
tolerance = 0.0001
)
expect_equal(
res3$data_array,
NULL
)
expect_equal(
as.vector(res3$lons)[1:5],
c(0.0, 3.6, 7.2, 10.8, 14.4)
)
expect_equal(
as.vector(res3$lats)[1:5],
c(-88.2, -84.6, -81.0, -77.4, -73.8)
)

})

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

test_that("5. dat4: irregular regrid", {
suppressWarnings(
res <- CDORemap(data4, lons4, lats4, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res1 <- CDORemap(data4_1, lons4, lats4, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res2 <- CDORemap(data4_2, lons4, lats4, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
suppressWarnings(
res3 <- CDORemap(data4_3, lons4, lats4, grid = 'r100x50', method = 'bil', crop = F)$data_array
)
# no data
suppressWarnings(
res4 <- CDORemap(NULL, lons4, lats4, grid = 'r100x50', method = 'bil', crop = F)
)
expect_equal(
as.vector(res),
as.vector(res1)
)
expect_equal(
as.vector(res),
as.vector(res2)
)
expect_equal(
as.vector(res),
as.vector(res3)
)
expect_equal(
res1[1:5, 50],
c(-1.795211, -1.795057, -1.794898, -1.794707, -1.794533),
tolerance = 0.0001
)
expect_equal(
res4$data_array,
NULL
)
expect_equal(
as.vector(res4$lons)[1:5],
c(0.0, 3.6, 7.2, 10.8, 14.4)
)
expect_equal(
as.vector(res4$lats)[1:5],
c(-88.2, -84.6, -81.0, -77.4, -73.8)
)

})


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

test_that("6. dat5: regular regrid, more dimensions", {
suppressWarnings(
res5 <- CDORemap(data5, lons = seq(1, 5.5, by = 0.5), lats = seq(10, 13.5, by = 0.5), 
                 grid = 'r360x181', method = 'bil', crop = T)
)
expect_equal(
as.vector(res5$lons),
1:5
)
expect_equal(
as.vector(res5$lats),
10:13
)
expect_equal(
as.vector(res5$data_array[1, 1, 1, , , 2, 1]),
c(seq(321, 353, by = 8), seq(401, 433, by = 8), seq(481, 513, by = 8), seq(561, 593, by = 8))
)

suppressWarnings(
res5_1 <- CDORemap(data5_1, lons = seq(1, 5.5, by = 0.5), lats = seq(10, 13.5, by = 0.5),
                 grid = 'r360x181', method = 'bil', crop = T)
)
expect_equal(
aperm(res5_1$data_array, c(1, 2, 3, 5, 6, 4, 7)),
res5$data_array
)
expect_equal(
as.vector(res5_1$lons),
1:5
)
expect_equal(
as.vector(res5_1$lats),
10:13
)
})

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

test_that("7. data6: regular regrid, descent order", {
  suppressWarnings(
    res6 <- CDORemap(data6, lats = lats6, lons = lons6, grid = 'r360x181', method = 'bil')
  )
  expect_equal(
    length(res6$lons),
    360
  )
  expect_equal(
    length(res6$lats),
    181
  )
  expect_equal(
    min(res6$lons),
    0
  )
  expect_equal(
    max(res6$lons),
    359
  )
  expect_equal(
    min(res6$lats),
    -90
  )
  expect_equal(
    max(res6$lats),
    90
  )
})

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

test_that("8. data7: regular grid, crop = T, global", {
  suppressWarnings(
    res7 <- CDORemap(data7, lons7, lats7, 't170grid', 'bil', TRUE)
  )
  res_lon7 <- res7$lons
  res_lat7 <- res7$lats
  expect_equal(
    dim(res7$data_array),
    c(lat = 256, lon = 512)
  )
  expect_equal(
    as.vector(res7$lats)[1:10],
    c(89.46282, 88.76695, 88.06697, 87.36606, 86.66480, 85.96337, 85.26185, 
      84.56026, 83.85864, 83.15699),
    tolerance = 0.000001
  )
  expect_equal(
    as.vector(res7$lons)[1:10],
    c(0.000000, 0.703125, 1.406250, 2.109375, 2.812500, 3.515625, 4.218750, 
      4.921875, 5.625000, 6.328125),
    tolerance = 0.000001
  )
  expect_equal(
    c(min(res_lon7), max(res_lon7), min(res_lat7), max(res_lat7)),
    c(0.00000, 359.29688, -89.46282, 89.46282),
    tolerance = 0.000001
  )
})
