check_recipe <- function(recipe, file, conf) {
  # recipe: yaml recipe already read it
  # file: name of the file to clarify messages
  # conf: configuration file read to load the tables of definitions
  # output: errors or the total number of workflow (vars x regions) to compute
  message(paste("Checking recipe", file))
  if (!any(names(recipe) %in% "Analysis")) {
    stop("The recipe should has a element 'Analysis'.")
  }
  params <- c('Horizon', 'Time', 'Variables', 'Region', 'Grid', 'Workflow', 'Datasets')
  if (!all(params %in% names(recipe$Analysis))) {
    stop(paste("The element 'Analysis' in the recipe should contain these",
         "elements:", paste(params, collapse = " ")))
  }
  horizons <- c('Subseasonal', 'Seasonal', 'Decadal')
  if (!any(horizons %in% recipe$Analysis$Horizon)) {
    stop("The element 'Horizon' in the recipe should be one of the followings:",
         paste(horizons, collapse = " "))
  }
  # more checks
  # ...
  # calculate number of workflows to create for each variable and 
  if (length(recipe$Analysis$Horizon) > 1) {
     stop("Only 1 Horizon can be specified in the recipe")
  }
  nvar <- length(recipe$Analysis$Variables)
  if (length(recipe$Analysis$Region) > 3) {
    stop("The section 'Region' in the recipe should be checked.",
         "Global, Countries and Regional elements are expected.")
  }
  if (!is.logical(recipe$Analysis$Region$Global)) {
    stop("The element 'Global' in Region should be logical.")
  }
  nregions <- 0
  if (recipe$Analysis$Region$Global == TRUE) {
    nregions <- 1
  }
  if (recipe$Analysis$Region$Countries == TRUE) {
    nregions <- nregions + 1
  }
  if ("Regional" %in% names(recipe$Analysis$Region)) {
    nregions <- nregions + length(recipe$Analysis$Region$Regional)
    limits <- c('latmin', 'latmax', 'lonmin', 'lonmax')
    for (i in 1:length(recipe$Analysis$Region$Regional)) {
      if (!all(limits %in% names(recipe$Analysis$Region$Regional[[i]]))) {
        stop("Each region defined in element 'Regional' should have 4 elements:",
             paste(limits, collapse = " "))
      }
      # are numeric? class list mode list 
    }
  }
  # Check workflow: need to define restrictions? 
  # e.g. only one calibration method
  nverifications <- check_number_of_dependent_verifications(recipe, conf)
  message("Recipe checked succsessfully.")
  return(nverifications)
}

check_number_of_dependent_verifications <- function(recipe, conf) {
  # Number of verifications depends on the variables and indicators requested
  # and the order of the workflow:
  # workflow: correction + indicator --> only 1 variable is calibrated
  # workflow: indicator + correction --> the indicator and the ecv are calibrated
  independent_verifications <- NULL
  dependent_verifications <- NULL
  dep <- 1
  if (is.null(recipe$Analysis$Variables$Indicators) || 
      (length(recipe$Analysis$Variables$Indicators) == 1 && 
       is.null(recipe$Analysis$Variables$ECVs))) {
  # look for duplications
    vars <- unlist(recipe$Analysis$Variables)
    if (any(duplicated(vars))) {
      stop("There are duplicated variables.")
    }
    independent_verifications <- as.vector(vars)
  } else if (length(names(recipe$Analysis$Variables)) == 2 || 
             length(recipe$Analysis$Variables$Indicators) > 1) {
    ecvs <- recipe$Analysi$Variables$ECVs
    inds <- recipe$Analysi$Variables$Indicators
    ind_table <- read_yaml(paste0(conf$code_dir,
                           "data_analysis/indicators_table.yml"))
    ind_table <- ind_table[unlist(inds)]
    vars_for_ind <- NULL
    # look for ecvs required to compute indicators
    for (ind in unlist(inds)) {
      if (is.null(ind_table[ind][[1]])) {
        stop("Check the name of the indicators.")
      }
      vars_for_ind <- c(vars_for_ind, ind_table[ind][[1]]$ECVs)
    }
    if (any(vars_for_ind %in% unlist(ecvs)) || 
        any(duplicated(vars_for_ind))) {
      # check workflow order to know the number of verifications to calculate
      if (all(c('Calibration', 'Indicators') %in% names(recipe$Analysis$Workflow))) {
        cal_pos <- which(names(recipe$Analysis$Workflow) == 'Calibration')
        ind_pos <- which(names(recipe$Analysis$Workflow) == 'Indicators')
        if (cal_pos < ind_pos) {
          workflow_independent <- FALSE
        } else {
          workflow_independent <- TRUE
        }
      }
    }
    vars <- unique(c(unlist(ecvs), unlist(vars_for_ind)))
    for (var in unlist(vars)) {
      if (var %in% vars_for_ind) {
        if (workflow_independent) {
          if (var %in% unlist(ecvs)) {
            varname <- var
          } else {
            varname <- NULL # avoid writting a ecv not requested by needed by the ind
          }
          independent_verifications <- c(independent_verifications, varname,
                         as.vector(unlist(inds[which(unlist(vars_for_ind %in% var))])))
        } else {
          if (var %in% unlist(ecvs)) {
            varname <- var
          } else {
            varname <- NULL
          }
          dependent_verifications[[dep]] <- c(varname,
                         as.vector(unlist(inds[which(unlist(vars_for_ind %in% var))])))
          dep = dep + 1
        }
      } else {
        independent_verifications <- var
      }
    }
  } else {
   stop("Only two types of 'Variables', named 'ECVs' and 'Indicators',",
         " are allawed.")
  }
  if (!is.null(independent_verifications)) {   
    message("The variables for independent verification are ", 
            paste(independent_verifications, collapse = " "))
  }
  if (!is.null(dependent_verifications)) {
    message("The variables for dependent verification are: ",
            paste(dependent_verifications, collapse = " "))
  }
  # remove unnecessary names in objects to be removed
  return(list(independent = independent_verifications, 
              dependent = dependent_verifications))
}
#workflow <- list(Calibration = list(method = 'SBC'),
#                 Skill = list(metric = 'RPSS'))
#ApplyWorkflow <- function(workflow) {

#res <- do.call('CST_BiasCorrection',
#               args = list(exp = lonlat_data$exp,
#                           obs = lonlat_data$obs))
   



