#'Scorecards load metrics from verification suite
#' 
#'Scorecards function to load saved data files. This function is created to 
#'load NetCDF files that contain 1 metric for each file. It calls startR::Start 
#'internally. The NetCDF file is supposed to have the following dimensions: 
#''longitude', 'latitude' and 'time'. If 'syear' is also a dimension, you must 
#'set the parameter 'syear' different to NULL.
#'
#'@param input_path A character string indicating the path where metrics output 
#'  files from verification suite are saved (or any other compatible files)
#'@param metrics A vector of character strings indicating the metrics name to 
#'  be loaded.
#'@param system A vector of character strings defining the names of the 
#'  system names following the archive.yml format from verification suite. 
#'  Accepted system names: 'ECMWF-SEAS5', 'DWD-GFCS2.1', 'CMCC-SPS3.5',
#'  'ecmwfs5','Meteo-France-System 7', 'UK-MetOffice-GloSea600', 'NCEP-CFSv2'.
#'@param reference A vector of character strings defining the names of 
#'  the references following the archive.yml format from verification suite 
#'  Pending to be test with more than one. The accepted names are: 'era5'.
#'@param var A character string following the format from 
#'  variable-dictionary.yml from verification suite (TO DO: multiple variables). 
#'  The accepted names are: 'psl', 'tas', 'sfcWind', 'prlr'.
#'@param period A character string indicating the start and end years of the 
#'  reference period (e.g. '1993-203')
#'@param start_months A vector indicating the numbers of the start months
#'@param forecast_months A vector indicating the numbers of the forecast months
#'@param syear Used when the NetCDF file contains a metric that has the 
#'  dimension 'syear'. It can be any value. If there is no 'syear' dimension, 
#'  you must set it to NULL. It is NULL by default.
#'
#'@return A is a list by system and reference containing an array of with 
#'   the following dimensions: longitude, latitude, forecast months, metrics, 
#'   start dates.
#'@examples
#'\dontrun{
#'loaded_metrics <- LoadMetrics(system = c('ECMWF-SEAS5','DWD-GFCS2.1'),
#'                              reference = 'ERA5',
#'                              var = 'tas',
#'                              period = '1993-2016',
#'                              metrics =  c('mean_bias', 'enscorr', 'rpss', 'crpss', 'enssprerr'),
#'                              start_months = sprintf("%02d", 1:12),
#'                              forecast_months = 1:6,
#'                              input_path = '/esarchive/scratch/nmilders/scorecards_data/input_data')
#'}
#'@import easyNCDF
#'@import multiApply
LoadMetrics <- function(input_path, metrics, var, system, reference, 
                        period = NULL, start_months = NULL, 
                        forecast_months = NULL, inf_to_na = FALSE, 
                        calib_method = NULL, syear = NULL) {

  
  ## Remove . from names
  system <- gsub('.','', system, fixed = T)
  reference <- gsub('.','', reference, fixed = T)
  
  ## Define empty list to saved data
  all_metrics <- sapply(system, function(x) NULL)
  ## Load data for each system
  for (sys in 1:length(system)) {
    ## Define empty list to saved data
    by_reference <- sapply(reference, function(x) NULL)
    ## Load data for each reference
    for (ref in 1:length(reference)) {
      ## Call function to load metrics data
      met <- .loadmetrics(input_path = input_path, # recipe$Run$output, 
                          system = system[sys],
                          reference = reference[ref],
                          var = var,
                          period = period, 
                          start_months = start_months,
                          forecast_months = forecast_months,
                          metrics = metrics, calib_method = calib_method,
                          syear = syear)
      ## Save metric data as array in reference list
      by_reference[[reference[ref]]] <- met
      ## Remove -Inf from crpss data if variable is precipitation
      if (inf_to_na) {
        by_reference[[reference]][by_reference[[reference]]==-Inf] <- NA      
      }
    } ## close loop on reference
    ## Save reference data in list of system
    all_metrics[[system[sys]]] <- by_reference
  } ## close loop on system
  
  return(all_metrics)
}

.loadmetrics <- function(input_path, metrics, var, system = NULL, 
                         reference = NULL, period = NULL, start_months = NULL, 
                         forecast_months = NULL, calib_method = NULL, 
                         syear = NULL) {
  # (1) Create the path to the files
  directory_path <- paste0(input_path, system, "/", reference, "/", 
                           calib_method, "/",  var, "/")
  file_path <- paste0(directory_path, "scorecards_", system, "_", reference, 
                      "_", var, "_$var$_", period, "_s", "$smonths$", ".nc")

  # (2) Create the startR arguments list
  if (is.null(forecast_months)) forecast_months <- 'all'
  if (is.null(start_months)) start_months <- 'all'
  
  args = list(dat = file_path,
              var = metrics,
              longitude = 'all',
              latitude = 'all',
              time = forecast_months,
              syear = "all",
              smonths = start_months,
              return_vars = list(longitude = 'dat',
                                 latitude = 'dat',
                                 time = NULL),
              metadata_dims = c('dat', 'var'),
              retrieve = TRUE)

  if (is.null(syear)) {
    args$syear <- NULL
  }

  # (3): Call startR
  loaded_metrics_start <- do.call(Start, args = args)
  
  return(loaded_metrics_start)
}
