"All of these functions are deprecated;   leaving here until fully cleaned from code"


upload_file_to_snowflake_stage <- function(file_fullpath, stage_name, prefix=NULL, tbl_out, timestamp=timeStamp(), wh=getSnowflakeWH(), dbname=getSnowflakeDB(), schema=getSnowflakeDB(), relativeTo=ingestDir, verbose=TRUE) {
  ## NEW FUNCTION upload_file_to_snowflake()
  {
    message("upload_file_to_snowflake_stage() deprecated, use upload_file_to_snowflake_stage()")
    ARGS <- collectArgs()
    return(do.call(upload_file_to_snowflake_stage, ARGS))
  }

  #  force(tbl_out); force(stage_name);
  #
  #  subfolder <- file_fullpath %>% subbucketNameFromFileName(.) %>% gsub("^/", "", .)
  #  if (subfolder == "")
  #    subfolder <- c()
  #
  #  "root/snowflake_stages/stage_name/"
  #  bucket_for_stage <- sfGetBucketFromStage(stage_name=stage_name, wh=wh, dbname=dbname, schema=schema, verbose=FALSE)
  #  bucket_for_file <- s3_p(root=NULL, bucket_for_stage, tbl_out, subfolder, file=basename(file_fullpath), warn_on_as.path=TRUE)
  #  "root/snowflake_stages/stage_name/tbl_dest/relative/path/onLocal/filename.ext"
  #
  #  s3_upload(file.local=file_fullpath, bucket=bucket_for_file)
}


sfPopulateTableFromBucket <- function(...) {
  warning("sfPopulateTableFromBucket() deprecated.\nUSE: sfPopulateTableFromStage() or sfPopulateTableFromFile()")
  if ("subfolder" %in% names(list(...)))
    stop ("subfolder has been deprecated.  Use bucket_relative_to_stage -- but also, double check your work first")

  sfPopulateTableFromStage(...)
}


sfPopulateTableFromFile <- function(
    file_name
  , tbl
  , stage_name=NULL
  , header
  , timestamp = timeStamp()
  , on_error=c("continue", "skip_file", "abort_statement")
  , delete_files_after_load=FALSE
  , validation_mode=FALSE
  , wh=getSnowflakeWH()
  , dbname=getSnowflakeDB()
  , schema=getSnowflakeSchema()
  , verbose.rows=verbose
  , verbose=TRUE
) {

  {
    message("sfPopulateTableFromFile() deprecated, use sfPopulateTable()")
    ARGS <- collectArgs(except=if (missing(header)) "header")
    return(do.call(sfPopulateTable, ARGS))
  }
  #  ## This function calls
  #  ##    upload_file_to_snowflake_stage()  then ...
  #  ##    sfPopulateTableFromStage() 
  #
  #  if (!missing(header))
  #    warning("'header' should be set when creating the file format. It is ignored in sfPopulateTableFromFile()", .call=FALSE)
  #
  #  ## UPLOAD THE FILE
  #  bucket_for_file <- upload_file_to_snowflake_stage(file=file_name, tbl_out=tbl, timestamp=timestamp, stage_name=stage_name, schema=schema, dbname=dbname)
  #
  #  ## The Stage and Filetype for the data load was created in the public schema
  #  sfPopulateTableFromStage(tbl=tbl, stage=stage_name, bucket=bucket_for_file, header=header, on_error=on_error, delete_files_after_load=delete_files_after_load, validation_mode=validation_mode, wh=wh, dbname=dbname, schema=schema, verbose.rows=verbose.rows, verbose=TRUE)
}

sfPopulateTableFromStage <- function(
    tbl
  , stage_name
  , bucket
  , bucket_relative_to_stage
  , header=FALSE  ## Logical or an integer
  , on_error=c("continue", "skip_file", "abort_statement")
  , delete_files_after_load=FALSE
  , validation_mode=FALSE
  , wh=getSnowflakeWH()
  , dbname=getSnowflakeDB()
  , schema=getSnowflakeSchema()
  , verbose.rows=verbose
  , verbose=TRUE
) {

  {
    message("sfPopulateTableFromStage() deprecated, use sfPopulateTable()")
    ARGS <- collectArgs(except=if (missing(header)) "header")
    return(do.call(sfPopulateTable, ARGS))
  }
  

## TODO 1:  Allow for override of these file format options
## This would involve changing the CREATE INTO statment format type
##    [FILE_FORMAT = (FORMAT_NAME = '<format_identifier>' | TYPE = <format_type> [ <file_format_options> ] ) ]
##    https://documentation.snowflakecomputing.com/manuals/sql-reference/sql/copy-into-table.html
##
  # list(
  # , FIELD_DELIMITER = NULL # '<character>' | 'NONE'
  # , RECORD_DELIMITER = NULL # '<character>' | 'NONE'
  # , SKIP_HEADER = NULL # <integer>
  # , DATE_FORMAT = NULL # '<string>' | 'AUTO'
  # , TIMESTAMP_FORMAT = NULL # '<string>' | 'AUTO'
  # , ESCAPE = NULL # '<character>' | 'NONE'
  # , ESCAPE_UNENCLOSED_FIELD = NULL # '<character>' | 'NONE'
  # , TRIM_SPACE = NULL # TRUE | FALSE
  # , FIELD_OPTIONALLY_ENCLOSED_BY = NULL # '<character>' | 'NONE'
  # , NULL_IF = NULL # ( '<string>' [, '<string>'] ... )
  # , ERROR_ON_COLUMN_COUNT_MISMATCH = NULL # TRUE | FALSE
  # )



## We want bucket_relative_to_stage;  However, generally we have the full bucket.
## Thus, we can calculate the bucket_relative_to_stage by finding bucket_for_stage

  if (missing(bucket_relative_to_stage)) {
    if (missing(bucket))
      stop ("at least one of bucket or bucket_relative_to_stage must be used")
    bucket_for_stage <- sfGetBucketFromStage(stage_name=stage_name, wh=wh, dbname=dbname, schema=schema, verbose=FALSE)
    bucket_relative_to_stage <- bucket %>% gsub(bucket_for_stage, "", .)
  }
  bucket_relative_to_stage %<>% gsub("^/", "", .)

  dstbl <- dbschematbl(dbname=dbname, schema=schema, tbl=tbl)
  on_error <- match.arg(on_error)

  if (verbose.rows)
    row_count.before_load <- qRowCount(tbl=tbl, schema=schema, dbname=dbname, wh=wh)

  QRY <- sprintf("
  COPY INTO %s 
    FROM @%s/%s
    ON_ERROR = %s
    PURGE = %s
    "
    , dstbl
    , stage_name
    , valueIfNull(bucket_relative_to_stage, "")
    , toupper(on_error)
    , isTRUE(delete_files_after_load)
    )

  if (isTRUE(validation_mode)) {
    QRY %<>% paste("VALIDATION_MODE = RETURN_ERRORS")
  }
  
  QRY %<>% paste0(";") %>% setQry

  ## EXECUTE
  ret <- sfQry(QRY, verbose=verbose, wh=wh, dbname=dbname, schema=schema)

  if (verbose.rows) {
    row_count.after_load <- qRowCount(tbl=tbl, schema=schema, dbname=dbname, wh=wh)
    (row_count.after_load - row_count.before_load) %>% formnumb(round=FALSE) %>% 
      sprintf("%s rows loaded", .) %>% cat("\n")
  }

  return(ret)
}
