library(CSTools)

##############################################
test_that("1. Sanity Checks", {
  # data
  expect_error(
    PeriodMax(data = NULL), 
    "Parameter 'data' cannot be NULL."
  )
  expect_error(
    PeriodMax('x'), 
    "Parameter 'data' must be numeric."
  )
  # time_dim
  expect_error(
    PeriodMax(array(1:10), time_dim = 1), 
    "Parameter 'time_dim' must be a character string."
  )
  expect_error(
    PeriodMax(array(1:10, dim = c(time = 10)), time_dim = 'ftime'), 
    "Parameter 'time_dim' is not found in 'data' dimension."
  )
  suppressWarnings(
    expect_equal(
      PeriodMax(array(1, c(x = 1)), time_dim = 'x'), 
      1
    )
  )
  expect_error(
    PeriodMax(1, dates = '2000-01-01', end = 3, start = 4),
    "Parameter 'start' and 'end' must be lists indicating the day and the month of the period start and end."
  )
  suppressWarnings(
    expect_equal(
      PeriodMax(array(1:10, c(time = 10))), 
      10
    )
  )
  data <- array(1:24, c(sdate = 2, time = 3, lon = 4))
  suppressWarnings(
    expect_equal(
      PeriodMax(data),
      array(c(5, 6, 11, 12, 17, 18, 23, 24), 
      c(sdate = 2, lon = 4))
    )
  )
  # Test dates warning
  expect_warning(
    PeriodMax(array(1:10, c(time = 10)), 
               dates = seq(as.Date("01-05-2000", format = "%d-%m-%Y"), 
                           as.Date("10-05-2000", format = "%d-%m-%Y"), by = 'day'),
               start = list(05, 02), end = list(05, 09)),
    paste0("Parameter 'dates' must have named dimensions if 'start' and 'end' ", 
           "are not NULL. All data will be used.")
  )
  # start and end when dates is not provided
  expect_warning(
    PeriodMax(array(1:10, c(time = 10)), 
               start = list(05, 02), end = list(05, 09)),
    paste0("Parameter 'dates' is NULL and the average of the full data ", 
           "provided in 'data' is computed.")
  )
})

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

test_that("2. Seasonal", {
  exp <- NULL
  exp$data <- array(1:(1 * 3 * 214 * 2),
                    c(memb = 1, sdate = 3, time = 214, lon = 2))
  exp$dims <- dim(exp$data)
  exp$attrs$Dates <- c(seq(as.Date("01-04-2000", format = "%d-%m-%Y"),
                           as.Date("31-10-2000", format = "%d-%m-%Y"), by = 'day'),
                       seq(as.Date("01-04-2001", format = "%d-%m-%Y"),
                           as.Date("31-10-2001", format = "%d-%m-%Y"), by = 'day'),
                       seq(as.Date("01-04-2002", format = "%d-%m-%Y"),
                           as.Date("31-10-2002", format = "%d-%m-%Y"), by = 'day'))
  dim(exp$attrs$Dates) <- c(time = 214, sdate = 3)
  class(exp) <- 's2dv_cube'
  output <- exp
  output$data <- array(c(max(exp$data[1,1,21:82,1]), max(exp$data[1,2,21:82,1]),
                         max(exp$data[1,3,21:82,1]), max(exp$data[1,1,21:82,2]),
                         max(exp$data[1,2,21:82,2]), max(exp$data[1,3,21:82,2])),
                       c(memb = 1, sdate = 3, lon = 2))
  expect_equal(
    CST_PeriodMax(exp, start = list(21, 4), end = list(21, 6))$data,
    output$data
  )
})

##############################################
test_that("3. Subset Dates and check time_bounds", {
  exp <- CSTools::lonlat_prec
  res <- CST_PeriodMax(data = CSTools::lonlat_prec, time_dim = 'ftime',
                        start = list(10, 03), end = list(20, 03))
  # Check dims
  expect_equal(
    dim(res$data), 
    res$dims
  )
  # Check Dates
  expect_equal(
    dim(res$data)['sdate'], 
    dim(res$attrs$Dates)
  )
  # Check time_bounds
  expect_equal(
    res$attrs$Dates, 
    res$attrs$time_bounds$start
  )
  expect_equal(
    dim(res$attrs$time_bounds$start), 
    dim(res$attrs$time_bounds$end)
  )
  # Check 'sdates'
  expect_equal(
    all(lubridate::month(res$attrs$time_bounds$start) == 3),
    TRUE
  )
  expect_equal(
    all(lubridate::day(res$attrs$time_bounds$start) == 10),
    TRUE
  )
  expect_equal(
    all(lubridate::month(res$attrs$time_bounds$end) == 03),
    TRUE
  )
  expect_equal(
    all(lubridate::day(res$attrs$time_bounds$end) == 20),
    TRUE
  )
})

