# WARNING - Generated by {fusen} from dev/flat_detect_chars_structure_datasets.Rmd: do not edit by hand

#' Detect character structure from datasets
#'
#' @param datasets_folderpath Character 1L. Folder path of datasets to process. These datasets must be at the root of the path
#' @param considered_extensions Character. Datasets file extensions to consider. Extensions must be one supported by the rio:: package
#' @param patterns Character. Patterns to detect across the datasets variables. Regex is supported
#' @param output_filepath Character 1L. Output folder path. 
#' @param get_output_in_session Logical 1L. If TRUE, the function return a list, such that each element element corresponds to pattern detection details for each considered dataset
#' @return If \code{get_output_in_session} is \code{TRUE}, a named list of data
#'   frames (one per dataset file), each with columns \code{var} (variable name),
#'   \code{any_defined_structure} (logical), and \code{examples} (character).
#'   The list is also saved as an RDS file at \code{output_filepath}.
#'   If \code{get_output_in_session} is \code{FALSE}, the function returns
#'   \code{NULL} invisibly and is called for its side effect of writing the RDS file.
#' @export
#'
#' @examples
#' mydir <- system.file("detect_chars_structure_datasets", package = "scrutr")
#' outfile <- file.path(tempdir(), "detect_college.rds")
#'
#' detect <- detect_chars_structure_datasets(
#'   datasets_folderpath = mydir,
#'   considered_extensions = "xlsx",
#'   patterns = "(?i)college",
#'   output_filepath = outfile,
#'   get_output_in_session = TRUE)
#'
#' # head(lapply(detect, head))
#'
#' file.exists(outfile)
#' unlink(outfile)
detect_chars_structure_datasets <- function (
  datasets_folderpath, 
  considered_extensions, 
  patterns, 
  output_filepath = file.path(
    datasets_folderpath, 
    paste0("detect_chars_structure_", basename(datasets_folderpath), ".rds")), 
  get_output_in_session = TRUE) {
  
  if (isFALSE(dir.exists(datasets_folderpath))) {
    stop("datasets_folderpath must be a valid folder path")
  }
  
  if (isFALSE(dir.exists(dirname(output_filepath)))) {
    stop("Folder path of output_filepath must be a valid one")
  }
  
  ext <- paste0(paste0("\\.", considered_extensions, "$"), collapse = "|")
  lfiles <- list.files(datasets_folderpath, full.names = TRUE)
  lfiles <- lfiles[grepl(ext, lfiles)]
  
  data_list <- lapply(lfiles, \(x) {

    dataname <- basename(x)
    data <- rio::import(x, trust = TRUE)
    # Coerce all columns to character so detect_chars_structure (which
    # requires character input) can be applied to every variable.
    data <- dplyr::mutate(data, dplyr::across(
      dplyr::everything(), as.character))
    data
  })
  
  det_structure_list <- lapply(
    data_list, \(each_data) 
    lapply(each_data, detect_chars_structure, 
           patterns = patterns, verbose = TRUE))
  
  det_structure_list2 <- lapply(det_structure_list, \(each_data) {
    
    tobind <- lapply(names(each_data), \(each_variable) {
      
      c("var" = each_variable, 
        "any_defined_structure" = each_data[[each_variable]][[1]], 
        "examples" = paste0(each_data[[each_variable]][[2]][
          1:min(10, length(each_data[[each_variable]][[2]]))], 
          collapse = " / "))
    })
    
    df_out <- as.data.frame(do.call(what = rbind, tobind))
    df_out[["any_defined_structure"]] <- as.logical(df_out[["any_defined_structure"]])
    df_out
  })
  
  det_structure_list2 <- stats::setNames(det_structure_list2, basename(lfiles))
  
  saveRDS(det_structure_list2, file = output_filepath)
  if (get_output_in_session) {det_structure_list2}}
