save_forecast <- function(recipe,
                          data_cube,
                          type = "hcst",
                          agg = "global",
                          outdir = NULL) {
  # Loops over the years in the s2dv_cube containing a hindcast or forecast
  # 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('longitude', 'latitude')
  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
  if (global_attributes$system == 'Multimodel'){
    calendar <- archive$System[[recipe$Analysis$Datasets$System$models[[1]]]]$calendar
  } else {
    calendar <- archive$System[[global_attributes$system]]$calendar
  }

  # Generate vector containing leadtimes
  dates <- as.PCICt(ClimProjDiags::Subset(data_cube$attrs$Dates, 'syear', 1),
                    cal = calendar)
  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
    if (type == 'hcst') {
      init_date <- as.PCICt(paste0(recipe$Analysis$Time$hcst_start, '-', 
                                   sprintf('%02d', init_month), '-01'),
                            cal = calendar)
    } else if (type == 'fcst') {
      init_date <- as.PCICt(paste0(recipe$Analysis$Time$fcst_year[1], '-',
                                   sprintf('%02d', init_month), '-01'),
                            cal = calendar)
    }
  } else {
    if (type == 'hcst') {
      init_date <- as.PCICt(paste0(recipe$Analysis$Time$hcst_start,
                            recipe$Analysis$Time$sdate),
                            format = '%Y%m%d', cal = calendar)
    } else if (type == 'fcst') {
      init_date <- as.PCICt(paste0(recipe$Analysis$Time$fcst_year,
                            recipe$Analysis$Time$sdate),
                            format = '%Y%m%d', cal = calendar)
    }
  }
  # Get time difference in hours
  leadtimes <- as.numeric(dates - init_date)/3600
  
  syears <- seq(1:dim(data_cube$data)['syear'][[1]])
  # expect dim = [sday = 1, sweek = 1, syear, time]
  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)
    }

    # Loop over each year in the data and save independently
    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, 'ensemble', 'time')))
      } else {
        fcst <- list(Reorder(fcst, c('country', 'ensemble', 'time')))
      }
  
      # Add metadata
      var.sdname <- dictionary$vars[[variable]]$standard_name
      if (tolower(agg) == "country") {
        dims <- c('Country', 'ensemble', 'time')
        var.expname <- paste0(variable, '_country') 
        var.longname <- paste0("Country-Aggregated ", var.longname)
        var.units <- subset_cube$attrs$Variable$metadata[[variable]]$units
      } else {
        dims <- c(lalo, 'ensemble', 'time')
        var.expname <- variable
        var.sdname <- var.sdname
        var.units <- subset_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
      if (fcst.horizon == 'decadal') {
        ## NOTE: Not good to use data_cube$load_parameters$dat1 because decadal
        ## data has been reshaped
        # fcst.sdate <- format(as.Date(data_cube$Dates$start[i]), '%Y%m%d')
  
        # 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))
        fcst.sdate <- format(fcst.sdate, '%Y%m%d')
  
      } else {
        fcst.sdate <- data_cube$attrs$load_parameters$dat1$file_date[[1]][i]
      }
  
      # Get time dimension values and metadata
      times <- .get_times(store.freq, fcst.horizon, leadtimes, fcst.sdate, calendar)
      time <- times$time
  
      # Generate name of output file
      outfile <- get_filename(outdir, recipe, variable, fcst.sdate,
                              agg, "exp")
    
      # Get grid data and metadata and export to netCDF
      if (tolower(agg) == "country") { 
        country <- get_countries(grid)
        ArrayToNc(append(country, time, fcst), 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 <- list(latlon$lat, latlon$lon, time)
        vars <- c(vars, fcst)
        ArrayToNc(vars, outfile)
      }
    }
  }
  info(recipe$Run$logger, paste("#####", toupper(type),
                                "SAVED TO NETCDF FILE #####"))
}
