#'Read recipe YAML file and create and store logfile info
#'
#'The purpose of this function is to read the recipe configuration for Auto-S2S
#'workflows and create logfiles stored in an the output directory specified in 
#'the recipe. It returns an object of class logger that stores information on 
#'the recipe configuration and errors.
#'
#'@param recipe_file path to a YAML file with Auto-S2S configuration recipe
#'@param disable_checks whether to disable the recipe checks
#'@param unique_ID whether to add a unique ID to the output directory
#'@return list contaning recipe with logger, log file name and log dir name
#'
#'@import log4r
#'@import yaml
#'
#'@examples
#'setwd("/esarchive/scratch/vagudets/repos/auto-s2s/")
#'library(yaml)
#'recipe <- prepare_outputs("modules/data_load/recipe_1.yml")
#'info(recipe$Run$logger, "This is an info message")
#'
#'@export

prepare_outputs <- function(recipe_file,
                            disable_checks = FALSE,
                            uniqueID = TRUE,
                            restructure = TRUE) {
  # recipe_file: path to recipe YAML file
  # disable_checks: If TRUE, does not perform checks on recipe
  # disable_uniqueID: If TRUE, does not add a unique ID to output dir
  recipe <- read_yaml(recipe_file)
  recipe$recipe_path <- recipe_file
  recipe$name <- tools::file_path_sans_ext(basename(recipe_file))

  output_dir = recipe$Run$output_dir
  # Create output folders
  if (!uniqueID) {
    folder_name <- paste0(gsub(".yml", "", gsub("/", "_", recipe$name)))
  } else {
    folder_name <- paste0(gsub(".yml", "", gsub("/", "_", recipe$name)), "_",
                          gsub(" ", "", gsub(":", "", gsub("-", "",
                                                           Sys.time()))))
  }
  recipe$Run$output_dir <- file.path(output_dir, folder_name)
  print("Saving all outputs to:")
  print(paste0(output_dir, folder_name))
  if (dir.exists(file.path(output_dir, folder_name))) {
    warning("The output directory already exists and files may be overwritten.")
  } else {
    dir.create(file.path(output_dir, folder_name, 'outputs'),
               recursive = T, showWarnings = F)
  }
  dir.create(file.path(output_dir, folder_name, 'logs', 'recipes'),
             recursive = T, showWarnings = F)
  # Copy recipe to output folder
  file.copy(recipe$recipe_path, file.path(output_dir, folder_name, 'logs',
                                          'recipes'))
  # Create log output file
  logfile <- file.path(output_dir, folder_name, 'logs', 'main.log')
  file.create(logfile)

  # Set default behaviour of logger
  if (is.null(recipe$Run)) {
    recipe$Run <- list(Loglevel = 'INFO', Terminal = TRUE)
  }
  if (is.null(recipe$Run$Loglevel)) {
    recipe$Run$Loglevel <- 'INFO'
  }
  if (!is.logical(recipe$Run$Terminal)) {
    recipe$Run$Terminal <- TRUE
  }
  # logger set-up
  if (recipe$Run$Terminal) {
    logger <- log4r::logger(threshold = recipe$Run$Loglevel,  
                            appenders = list(console_appender(layout = default_log_layout()),
                                             file_appender(logfile, append = TRUE,   
                                                           layout = default_log_layout())))
  } else {
    logger <- log4r::logger(threshold = recipe$Run$Loglevel,
                            appenders = list(file_appender(logfile, append = TRUE,             
                                             layout = default_log_layout())))
  }
  recipe$Run$logger <- logger
  recipe$Run$logfile <- logfile

  # Set up default filesystem
  if (is.null(recipe$Run$filesystem)) {
    recipe$Run$filesystem <- "esarchive"
    warn(recipe$Run$logger,
         "Filesystem not specified in the recipe. Setting it to 'esarchive'.")
  }
  # Restructure the recipe to make the atomic recipe more readable
  if (restructure) {
  recipe <- restructure_recipe(recipe)
  }
  # Run recipe checker
  if (disable_checks) {
    warn(recipe$Run$logger,
         "Recipe checks disabled. The recipe will not be checked for errors.")
  } else {
    check_recipe(recipe)
  }
  return(recipe)
}
