context("Decadal monthly data - 1")

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

source("modules/Loading/Loading.R")
source("modules/Calibration/Calibration.R")
source("modules/Skill/Skill.R")
source("modules/Saving/Saving.R")
source("modules/Visualization/Visualization.R")

recipe_file <- "tests/recipes/recipe-decadal_monthly_1.yml"
recipe <- prepare_outputs(recipe_file)
archive <- read_yaml(paste0(recipe$Run$code_dir, "conf/archive_decadal.yml"))$archive

# Load datasets
suppressWarnings({invisible(capture.output(
data <- Loading(recipe)
))})

# Calibrate datasets
suppressWarnings({invisible(capture.output(
  calibrated_data <- Calibration(recipe, data)
))})

# Compute skill metrics
suppressWarnings({invisible(capture.output(
skill_metrics <- Skill(recipe, calibrated_data)
))})
suppressWarnings({invisible(capture.output(
probs <- Probabilities(recipe, calibrated_data)
))})

# Plotting
suppressWarnings({invisible(capture.output(
Visualization(recipe = recipe, data = calibrated_data,
	      skill_metrics = skill_metrics, probabilities = probs,
              significance = T)
))})

#======================================

test_that("1. Loading", {

expect_equal(
is.list(data),
TRUE
)
expect_equal(
names(data),
c("hcst", "fcst", "obs")
)
expect_equal(
class(data$hcst),
"s2dv_cube"
)
expect_equal(
class(data$fcst),
"s2dv_cube"
)
expect_equal(
class(data$obs),
"s2dv_cube"
)
expect_equal(
names(data$hcst),
c("data", "dims", "coords", "attrs")
)
expect_equal(
names(data$hcst),
names(data$fcst)
)
expect_equal(
names(data$hcst),
names(data$obs)
)
expect_equal(
dim(data$hcst$data),
c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 4, time = 3, latitude = 5, longitude = 4, ensemble = 2)
)
expect_equal(
dim(data$fcst$data),
c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 3, latitude = 5, longitude = 4, ensemble = 2)
)
expect_equal(
dim(data$hcst$attr$Dates),
c(sday = 1, sweek = 1, syear = 4, time = 3)
)
expect_equal(
as.vector(aperm(drop(data$hcst$data), c(5, 1:4))[, 1:2,1,2,3]),
c(291.3831, 291.6227, 292.3012, 290.9779),
tolerance = 0.0001
)
expect_equal(
mean(data$hcst$data),
287.3804,
tolerance = 0.0001
)
expect_equal(
range(data$hcst$data),
c(281.7395, 294.2467),
tolerance = 0.0001
)
expect_equal(
(data$hcst$attrs$Dates)[1],
as.POSIXct("1991-11-16", tz = 'UTC')
)
expect_equal(
(data$hcst$attrs$Dates)[2],
as.POSIXct("1992-11-16", tz = 'UTC')
)
expect_equal(
(data$hcst$attrs$Dates)[5],
as.POSIXct("1991-12-16 12:00:00", tz = 'UTC')
)
expect_equal(
(data$hcst$attrs$Dates)[10],
as.POSIXct("1993-01-16 12:00:00", tz = 'UTC')
)

})

#======================================
test_that("2. Calibration", {

expect_equal(
is.list(calibrated_data),
TRUE
)
expect_equal(
names(calibrated_data),
c("hcst", "obs", "fcst")
)
expect_equal(
class(calibrated_data$hcst),
"s2dv_cube"
)
expect_equal(
class(calibrated_data$fcst),
"s2dv_cube"
)
expect_equal(
dim(calibrated_data$hcst$data),
c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 4, time = 3, latitude = 5, longitude = 4,  ensemble = 2)
)
expect_equal(
dim(calibrated_data$fcst$data),
c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 3, latitude = 5, longitude = 4, ensemble = 2)
)
expect_equal(
mean(calibrated_data$fcst$data),
291.8375,
tolerance = 0.0001
)
expect_equal(
mean(calibrated_data$hcst$data),
289.6679,
tolerance = 0.0001
)
expect_equal(
as.vector(aperm(drop(calibrated_data$hcst$data), c(5, 1:4))[1, , 2, 3, 4]),
c(286.3895, 286.6408, 290.6652, 288.3759),
tolerance = 0.0001
)
expect_equal(
range(calibrated_data$fcst$data),
c(287.2173, 297.4578),
tolerance = 0.0001
)

})


#======================================
test_that("3. Metrics", {

expect_equal(
is.list(skill_metrics),
TRUE
)
expect_equal(
names(skill_metrics),
c("rpss", "rpss_significance")
)
expect_equal(
class(skill_metrics$rpss),
"array"
)
expect_equal(
dim(skill_metrics$rpss),
c(var = 1, time = 3, latitude = 5, longitude = 4)
)
expect_equal(
dim(skill_metrics$rpss_significance),
dim(skill_metrics$rpss)
)
expect_equal(
as.vector(drop(skill_metrics$rpss)[, 2, 3]),
c(-0.2857143, -1.2500000, -1.8928571),
tolerance = 0.0001
)
expect_equal(
as.vector(drop(skill_metrics$rpss_significance)[, 2, 3]),
rep(FALSE, 3)
)

# Probs
expect_equal(
names(probs),
c('probs', 'probs_fcst', 'percentiles')
)
expect_equal(
names(probs$probs),
c('prob_b33', 'prob_33_to_66', 'prob_a66', 'prob_b10', 'prob_10_to_90', 'prob_a90')
)
expect_equal(
names(probs$percentiles),
c('percentile_33', 'percentile_66', 'percentile_10', 'percentile_90')
)
expect_equal(
dim(probs$probs$prob_b33),
c(var = 1, syear = 4, time = 3, latitude = 5, longitude = 4)
)
expect_equal(
dim(probs$percentiles$percentile_33),
c(var = 1, time = 3, latitude = 5, longitude = 4)
)
expect_equal(
as.vector(probs$probs$prob_b33[, , 1, 2, 2]),
c(0.0, 0.5, 0.0, 1.0)
)
expect_equal(
as.vector(probs$probs$prob_10_to_90[, , 1, 2, 2]),
c(1.0, 1.0, 0.5, 0.5)
)
expect_equal(
as.vector(probs$percentiles$percentile_33[, , 1, 2]),
c(293.7496, 287.4263, 285.8295),
tolerance = 0.0001
)
expect_equal(
as.vector(probs$percentiles$percentile_10[, , 1, 2]),
c(293.1772, 286.9533, 284.7887),
tolerance = 0.0001
)

})

#======================================

test_that("4. Saving", {
outputs <- paste0(recipe$Run$output_dir, "/outputs/")
expect_equal(
all(basename(list.files(outputs, recursive = T)) %in%
c("tas_19911101.nc", "tas_19921101.nc", "tas_19931101.nc", "tas_19941101.nc", "tas_20211101.nc", 
  "tas-obs_19911101.nc", "tas-obs_19921101.nc", "tas-obs_19931101.nc", "tas-obs_19941101.nc",
  "tas-percentiles_month11.nc", "tas-probs_19911101.nc", "tas-probs_19921101.nc",
  "tas-probs_19931101.nc", "tas-probs_19941101.nc", "tas-probs_20211101.nc", "tas-skill_month11.nc")),
TRUE
)
# open the files and check values/attributes?
#expect_equal(
#)

expect_equal(
length(list.files(outputs, recursive = T)),
16
)

})


test_that("5. Visualization", {
plots <- paste0(recipe$Run$output_dir, "/plots/")
expect_equal(
all(basename(list.files(plots, recursive = T)) %in%
c("forecast_ensemble_mean-2021.png", "forecast_most_likely_tercile-2021.png",
  "rpss.png")),
TRUE
)
expect_equal(
length(list.files(plots, recursive = T)),
3
)

})

# Delete files
unlink(recipe$Run$output_dir, recursive = TRUE)

#==============================================================

# Compare with 2 forecast

recipe_file <- "tests/recipes/recipe-decadal_monthly_1b.yml"
recipe <- prepare_outputs(recipe_file)
archive <- read_yaml(paste0(recipe$Run$code_dir, "conf/archive_decadal.yml"))$archive

# Load datasets
suppressWarnings({invisible(capture.output(
data_b <- Loading(recipe)
))})

# Calibrate datasets
suppressWarnings({invisible(capture.output(
  calibrated_data_b <- Calibration(recipe, data_b)
))})

# Compute skill metrics
suppressWarnings({invisible(capture.output(
skill_metrics_b <- Skill(recipe, calibrated_data_b)
))})
suppressWarnings({invisible(capture.output(
probs_b <- Probabilities(recipe, calibrated_data_b)
))})


test_that("6. Compare with two sdates in forecast", {


expect_equal(
c(ClimProjDiags::Subset(data_b$fcst$data, 'syear', 2, drop = F)),
c(data$fcst$data)
)

expect_equal(
c(ClimProjDiags::Subset(calibrated_data_b$fcst$data, 'syear', 2, drop = F)),
c(calibrated_data$fcst$data)
)

expect_equal(
skill_metrics_b,
skill_metrics
)

expect_equal(
lapply(probs_b$probs_fcst, ClimProjDiags::Subset, 'syear', 2),
probs$probs_fcst
)

unlink(recipe$Run$output_dir, recursive = TRUE)
})
