

compute_statistics <- function(recipe, data, agg = 'global'){
  
  # data$hcst: s2dv_cube containing the hindcast
  
  # obs: s2dv_cube containing the observations
  # recipe: auto-s2s recipe as provided by read_yaml
  
  time_dim <- 'syear'
  memb_dim <- 'ensemble'
  ncores <- recipe$Analysis$ncores

  # ## Remove unwanted dimensions
  obs_data <- Subset(data$obs$data, along = c('dat', 'sday', 'sweek', 'ensemble'), indices = list(1,1,1,1) , drop = 'selected')
  hcst_data <- Subset(data$hcst$data, along = c('dat', 'sday', 'sweek'), indices = list(1,1,1) , drop = 'selected')
  
  ## Repeat ensemble members for obs
  obs_data_ens <- InsertDim(data = obs_data, pos = length(dim(obs_data))+1, lendim = 25, name = 'ensemble')
  
  # obs_data <- adrop(data$obs$data, drop = 9)
  # obs_data_ens <- InsertDim(data = obs_data, pos = 9, lendim = 25, name = 'ensemble')
  
  
  statistics_list <- tolower(recipe$Analysis$Workflow$Statistics$metric)
  
  statistics_metrics <- list()
  
  for (stat in strsplit(statistics_list, ", | |,")[[1]]) {
    # Whether the fair version of the metric is to be computed
    if (stat %in% c('cov', 'covariance')) {
      
     covariance <- Apply(data = list(x = obs_data_ens, y = hcst_data), 
                         target_dims = c(time_dim, memb_dim),
                         fun = function(x,y){cov(as.vector(x),as.vector(y), 
                                                 use = "everything", 
                                                 method = "pearson")})$output1
      
     statistics_metrics[[ stat ]] <- covariance
      
    } ## close if on covariance
    
    
    if (stat %in% c('std', 'standard_deviation')) {
      
      ## Calculate standard deviation
      std_hcst <- Apply(data = hcst_data, 
                        target_dims = c(time_dim, memb_dim), 
                        fun = 'sd')$output1
      
      std_obs <- Apply(data = obs_data, 
                       target_dims = c(time_dim), 
                       fun = 'sd')$output1
      
      statistics_metrics[['std_hcst']] <- std_hcst
      statistics_metrics[['std_obs']] <- std_obs
      
    } ## close if on std
    
    if (stat %in% c('var', 'variance')) {
      
      ## Calculate standard deviation
      var_hcst <- (Apply(data = hcst_data, 
                         target_dims = c(time_dim, memb_dim), 
                         fun = 'sd')$output1)^2
      
      var_obs <- (Apply(data = obs_data, 
                        target_dims = c(time_dim), 
                        fun = 'sd')$output1)^2
      
      statistics_metrics[['var_hcst']] <- var_hcst
      statistics_metrics[['var_obs']] <- var_obs
      
    } ## close if on variance
 
    if (stat == 'n_eff') {   
    
      n_eff <- s2dv::Eno(data = obs_data, time_dim = time_dim, na.action = na.pass, ncores = ncores)
    
      statistics_metrics[['n_eff']] <- n_eff
      
    } ## close on n_eff  
  }
  
  info(recipe$Run$logger, "##### STATISTICS COMPUTATION COMPLETE #####")
  .log_memory_usage(recipe$Run$logger, when = "After statistics computation")
 
   # Save outputs
  if (recipe$Analysis$Workflow$Skill$save != 'none') {
    info(recipe$Run$logger, "##### START SAVING STATISTICS #####")
  }
  recipe$Run$output_dir <- paste0(recipe$Run$output_dir,
                                  "/outputs/Statistics/")
  
  if (recipe$Analysis$Workflow$Statistics$save == 'all') {
    # Save all statistics
      save_metrics_scorecards(recipe = recipe, skill = statistics_metrics, ## Not able to save data with these dimensions
                   data_cube = data$hcst, agg = agg) ## The length of parameter 'order' should be the same with the dimension length of parameter 'data'. 
  }
  
  # Return results
  return(statistics_metrics)
}  

