save_observations <- function(recipe,
                              data_cube,
                              agg = "global",
                              outdir = NULL) {
  # Loops over the years in the s2dv_cube containing the observations and
  # exports each year to a netCDF file.
  # data_cube: s2dv_cube containing the data and metadata
  # recipe: the auto-s2s recipe
  # outdir: directory where the files should be saved
  # agg: aggregation, "global" or "country"

  lalo <- c("latitude", "longitude")
  archive <- get_archive(recipe)
  dictionary <- read_yaml("conf/variable-dictionary.yml")
  global_attributes <- .get_global_attributes(recipe, archive)
  fcst.horizon <- tolower(recipe$Analysis$Horizon)
  store.freq <- recipe$Analysis$Variables$freq
  calendar <- archive$Reference[[global_attributes$reference]]$calendar

  ## TODO: Move to a separate function?
  if (fcst.horizon == 'decadal') {
    ## Method 1: Use the first date as init_date. But it may be better to use 
    ## the real initialized date (ask users)
    # init_date <- as.Date(data_cube$Dates$start[1], format = '%Y%m%d')
    ##  Method 2: use initial month
    # init_month <- archive$System[[recipe$Analysis$Datasets$System$name]]$initial_month
    # init_date <- as.PCICt(paste0(recipe$Analysis$Time$hcst_start, '-', 
    #                              sprintf('%02d', init_month), '-01'),
    #                       cal = calendar)
    init_date <- as.PCICt(paste0(as.numeric(recipe$Analysis$Time$hcst_start)+1, 
                                 '-01-01'), cal = calendar)
  } else if (fcst.horizon == 'seasonal') {
    init_date <- as.PCICt(paste0(recipe$Analysis$Time$hcst_start,
                          recipe$Analysis$Time$sdate),
                          format = '%Y%m%d', cal = calendar)
  } else if (fcst.horizon == 'subseasonal') {
    init_date <- as.PCICt(as.character(recipe$Analysis$Time$sdate),
                          format = '%Y%m%d', cal = calendar)
  }

  syears <- seq(1:dim(data_cube$data)['syear'][[1]])
  ## expect dim = [sday = 1, sweek = 1, syear, time]
  if (fcst.horizon == "subseasonal") {
    syears_val <- recipe$Analysis$Time$hcst_start:recipe$Analysis$Time$hcst_end
  } else { 
    syears_val <- lubridate::year(data_cube$attrs$Dates[1, 1, , 1])
  }

  # Loop over variables
  for (var in 1:data_cube$dims[['var']]) {
    subset_cube <- CST_Subset(data_cube, along = 'var', indices = var,
                              drop = F, var_dim = 'var', dat_dim = 'dat')
    variable <- subset_cube$attrs$Variable$varName
    var.longname <- subset_cube$attrs$Variable$metadata[[variable]]$long_name

    # Create output directory
    outdir <- get_dir(recipe = recipe, variable = variable)
    if (!dir.exists(outdir)) {
      dir.create(outdir, recursive = T)
    }
      
    for (i in syears) {
      # Select year from array and rearrange dimensions
      fcst <- ClimProjDiags::Subset(subset_cube$data, 'syear', i, drop = T)
      if (!("time" %in% names(dim(fcst)))) {
        dim(fcst) <- c("time" = 1, dim(fcst))
      }
      if (tolower(agg) == "global") {
        fcst <- list(Reorder(fcst, c(lalo, 'time')))
      } else if (tolower(agg) == "region") {
        fcst <- list(Reorder(fcst, c("region", "time")))
      } else {
        fcst <- list(Reorder(fcst, c('country', 'time')))
      }

      # Add metadata
      var.sdname <- dictionary$vars[[variable]]$standard_name
      if (tolower(agg) == "country") {
        dims <- c('Country', 'time')
        var.expname <- paste0(variable, '_country') 
        var.longname <- paste0("Country-Aggregated ", var.longname)
        var.units <- data_cube$attrs$Variable$metadata[[variable]]$units
      } else if (tolower(agg) == "region") {
        dims <- c("region", "time")
        var.expname <- variable
        var.sdname <- var.sdname
        var.longname <- paste0("Region-aggregated ", var.longname)
        var.units <- subset_cube$attrs$Variable$metadata[[variable]]$units
      } else {
        dims <- c(lalo, 'time')
        var.expname <- variable
        var.units <- data_cube$attrs$Variable$metadata[[variable]]$units
      }
    
      metadata <- list(fcst = list(name = var.expname,
                                   standard_name = var.sdname,
                                   long_name = var.longname,
                                   units = var.units))
      attr(fcst[[1]], 'variables') <- metadata
      names(dim(fcst[[1]])) <- dims
      # Add global attributes
      attr(fcst[[1]], 'global_attrs') <- global_attributes
      
      # Select start date. The date is computed for each year, and adapted for
      # consistency with the hcst/fcst dates, so that both sets of files have
      # the same name pattern.
      ## Because observations are loaded differently in the daily vs. monthly
      ## cases, different approaches are necessary.
      if (fcst.horizon %in% c('subseasonal', 'decadal')) {
        # init_date is like "1990-11-01"
        init_date <- as.POSIXct(init_date)
        fcst.sdate <- init_date + lubridate::years(syears_val[i] - lubridate::year(init_date))
      } else {
        if (store.freq == "monthly_mean") {
          fcst.sdate <- data_cube$attrs$load_parameters$dat1$file_date[[1]][i]
          fcst.sdate <- as.Date(paste0(fcst.sdate, "01"), '%Y%m%d')
        } else {
          fcst.sdate <- as.Date(data_cube$attrs$Dates[i])
        }
      }

      # Ensure the year is correct if the first leadtime goes to the next year
      init_date <- as.POSIXct(init_date)
      if (lubridate::month(fcst.sdate) < lubridate::month(init_date)) {
        lubridate::year(fcst.sdate) <- lubridate::year(fcst.sdate) + 1
      }
      # Ensure that the initialization month is consistent with the hindcast
      lubridate::month(fcst.sdate) <- lubridate::month(init_date)
      fcst.sdate <- format(fcst.sdate, format = '%Y%m%d')

      # Get time dimension values and metadata
      times <- .get_times(recipe, data_cube, fcst.sdate, calendar, init_date)

      # Generate name of output file
      outfile <- get_filename(outdir, recipe, variable,
                              fcst.sdate, agg, "obs")
    
      # Get grid data and metadata and export to netCDF
      if (tolower(agg) == "country") { 
        country <- get_countries(grid)
        ArrayToNc(append(country, times$time, fcst), outfile)
      } else if (tolower(agg) == "region") {
        region <- .get_region(data_cube)
        vars <- c(times, region, fcst)
        ArrayToNc(vars, outfile)
      } else {
        latitude <- data_cube$coords$lat[1:length(data_cube$coords$lat)]
        longitude <- data_cube$coords$lon[1:length(data_cube$coords$lon)]
        latlon <- .get_latlon(latitude, longitude)
        # Compile variables into a list and export to netCDF
        vars <- c(times, latlon, fcst)
        ArrayToNc(vars, outfile)
      }
    }
  }
  info(recipe$Run$logger, "##### OBS SAVED TO NETCDF FILE #####")
}
