# recipe
## Time_aggregation$execute YES/NO
## Time_aggregation$method accumulated or average
## Time_aggregation$user_def for decadal
## Time_aggregation$ini based on forecast time
## Time_aggregation$end based on forecast time
# For date definition of period aggregation consider using Indicators module
## ini = 2, end = 3 with monthly freq would be a 2 months agg
source("modules/Aggregation/R/agg_ini_end.R")

Aggregation <- function(recipe, data) {

  ## TODO: Move checks to recipe checker
  ncores <- recipe$Analysis$ncores # is it already checked? NULL or number
  na.rm <- ifelse(is.null(recipe$Analysis$remove_NAs), 
                  TRUE, recipe$Analysis$remove_NAs) # is it already checked? TRUE/FALSE
  if (isTRUE(recipe$Analysis$Workflow$Time_aggregation$execute)) {
    # original freq
    raw_freq <- tolower(recipe$Analysis$Variable$freq)
    custom <- recipe$Analysis$Workflow$Time_aggregation$user_def
    ini <- recipe$Analysis$Workflow$Time_aggregation$ini
    end <- recipe$Analysis$Workflow$Time_aggregation$end
    method <- tolower(recipe$Analysis$Workflow$Time_aggregation$method)
    ## Instead of raw freq may be better to use ini/end
    ##    if (raw_freq %in% c('daily', 'daily_mean', 'weekly', 'weekly_mean')) {
    if (!is.null(ini) && !is.null(end)) {
      # calculate aggregations from fday1 to fday2
      # calculate aggregations from fweek1 to fweek2
      # other cases could be indicators or other original freq
      if (length(ini) == length(end)) {
        res <- sapply(1:length(data), function(x) {
                      if (!is.null(data[[x]])) {
                        result <- agg_ini_end(data[x], method = method,
                                              na.rm = na.rm, ncores = ncores,
                                              ini = ini, end = end, indices = NULL)
                      } else {
                        result <- data[x]
                      }}, simplify = TRUE)
      }
    } else if (!is.null(custom)) {
      # calCUlate aggregations from fmonth1 to ftmonth2
      # for decadal, it makes sense to get all seasons and annual means too
      ## Ex: January, February, March for decadal simulations aggregation
      ## custom <- sort(c(seq(1,120, 12), seq(2,120,13), seq(3, 120, 14)))
      ## TODO: Remove this check? Already in check_recipe()
      if (is.list(custom)) {
        res <- sapply(1:length(data), function(x) {
                      if (!is.null(data[[x]])) {
                        result <- agg_ini_end(data[x], method, na.rm, ncores,
                                              indices = custom,
                                              ini = NULL, end = NULL)
                      } else {
                        result <- data[x]
                      }}, simplify = TRUE)
      } else {
        stop("Time_aggregation$user_def is not a list")
      }
    }
    info(recipe$Run$logger,
         "##### TIME AGGREGATION COMPLETE #####")
    return(res)
  } else {
    warn(recipe$Run$logger,
         paste("The Aggregation module has been called but parameter",
               "Time_aggregation:execute is set to 'no' in the recipe.",
               "The data is returned unchanged."))
    return(data)
  }
}
