## TODO: Save obs percentiles
## TODO: Insert vardim to simplify the code?

source("modules/Saving/R/get_dir.R")
source("modules/Saving/R/get_filename.R")
source("modules/Saving/R/Utils.R")
source("modules/Saving/R/save_forecast.R")
source("modules/Saving/R/save_observations.R")
source("modules/Saving/R/save_metrics.R")
source("modules/Saving/R/save_corr.R")
source("modules/Saving/R/save_probabilities.R")
source("modules/Saving/R/save_percentiles.R")
source("modules/Saving/R/get_time.R")
source("modules/Saving/R/get_latlon.R")
source("modules/Saving/R/get_global_attributes.R")
source("modules/Saving/R/drop_dims.R")

Saving <- function(recipe, data,
		   skill_metrics = NULL,
		   probabilities = NULL,
                   agg = 'global',
		   archive = NULL) {
  # Wrapper for the saving functions.
  # recipe: The auto-s2s recipe
  # archive: The auto-s2s archive
  # data: output of load_datasets()
  # data: output of calibrate_datasets()
  # skill_metrics: output of compute_skill_metrics()
  # probabilities: output of compute_probabilities()
  # mean_bias: output of compute_mean_bias()

  # Sanity checks
  if (is.null(recipe)) {
    error(recipe$Run$logger, "The 'recipe' parameter is mandatory.")
    stop()
  }

  if (is.null(data)) {
    error(recipe$Run$logger,
          paste("The 'data' parameter is mandatory. It should be a list",
                "of at least two s2dv_cubes containing the hcst and obs."))
    stop()
  }

  # Separate ensemble correlation from the rest of the metrics, as it has one
  # extra dimension "ensemble" and must be saved to a different file
  if ("corr_individual_members" %in% names(skill_metrics)) {
    corr_metric_names <- grep("^corr_individual_members", names(skill_metrics))
    corr_metrics <- skill_metrics[corr_metric_names]
    skill_metrics <- skill_metrics[-corr_metric_names]
    if (length(skill_metrics) == 0) {
      skill_metrics <- NULL
    }
  } else {
    corr_metrics <- NULL
  }

  # Iterate over variables to subset s2dv_cubes and save outputs
  save_forecast(recipe = recipe,
                data_cube = data$hcst,
                outdir = outdir[var],
                type = 'hcst')
  if (!is.null(data$fcst)) {
    save_forecast(recipe = recipe, 
                  data_cube = data$fcst,
                  outdir = outdir[var],
                  type = 'fcst')
  }
  save_observations(recipe = recipe, 
                    data_cube = data$obs,
                    outdir = outdir[var])

  # Export skill metrics
  if (!is.null(skill_metrics)) {
      save_metrics(recipe = recipe,
                   metrics = skill_metrics,
                   data_cube = data$hcst, agg = agg,
                   outdir = outdir[var])
  }
  if (!is.null(corr_metrics)) {
    save_corr(recipe = recipe,
              skill = corr_metrics, 
              data_cube = data$hcst,
              outdir = outdir[var])
  # Export probabilities onto outfile
  if (!is.null(probabilities)) {
      save_percentiles(recipe = recipe,
                       percentiles = probabilities$percentiles, 
                       data_cube = data$hcst,
                       outdir = outdir[var])
      save_probabilities(recipe = recipe,
                         probs = probabilities$probs,
                         data_cube = data$hcst,
                         outdir = outdir[var],
                         type = "hcst")
      if (!is.null(probabilities$probs_fcst)) {
        save_probabilities(recipe = recipe,
                           probs = probabilities$probs_fcst,
                           data_cube = data$fcst,
                           outdir = outdir[var],
                           type = "fcst")
      }
    }
  }
}
