/** \file file_util.h
 *  File utility functions
 */

// Copyright (C) 2014-2024 Sanford Rockowitz <rockowitz@minsoft.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#ifndef FILE_UTIL_H_
#define FILE_UTIL_H_

/** \cond */
#include <dirent.h>
#include <glib-2.0/glib.h>
#include <stdbool.h>
#include <stdio.h>
/** \endcond */

#include "error_info.h"
#include "file_util_base.h"

Error_Info * file_getlines_errinfo(
      const char *  filename,
      GPtrArray *   lines);

char * file_get_first_line(
      const char *  fn,
      bool          verbose);

int file_get_last_lines(
      const char *  fn,
      int           maxlines,
      GPtrArray**   line_array_loc,
      bool          verbose);

GByteArray * read_binary_file(
      const char *  fn,
      int           est_size,
      bool          verbose);

char * read_file_single_string(
      const char * filename,
      bool         verbose);

bool any_file_exists(
      const char * fqfn);

bool regular_file_exists(
      const char *  fqfn);

bool directory_exists(
      const char *  fqfn);

/** Signature of Filter function for get_filenames_by_filter() */
typedef int (*Dirent_Filter)(
      const struct dirent *end);

GPtrArray * get_filenames_by_filter(
      const char *  dirnames[],
      Dirent_Filter filter_func);

int filename_for_fd(
      int           fd,
      char**        fn_loc);

char * filename_for_fd_t(
      int           fd);

/** Signature of filename filter function passed to #dir_foreach(). */
typedef bool (*Filename_Filter_Func)(
      const char *  simple_fn);

typedef bool (*Filename_Filter_Func_With_Arg)(
      const char *  simple_fn, const char * arg);

/** Signature of the filter function passed to #dir_ordered_foreach,
 *  #dir_filtered_ordered_foreach
 */
typedef bool (*Dir_Filter_Func) (
      const char * dirname, const char * simple_fn);

/** Signature of function called by #dir_foreach to process each file. */
typedef void (*Dir_Foreach_Func)(
      const char *  dirname,
      const char *  fn,
      void *        accumulator,
      int           depth);

void dir_foreach(
      const char *          dirname,
      Filename_Filter_Func  fn_filter,
      Dir_Foreach_Func      func,
      void *                accumulator,
      int                   depth);

void dir_ordered_foreach(
      const char *          dirname,
      Filename_Filter_Func  fn_filter,
      GCompareFunc          compare_func,
      Dir_Foreach_Func      func,
      void *                accumulator,
      int                   depth);

void dir_ordered_foreach_with_arg(
      const char *          dirname,
      Filename_Filter_Func_With_Arg  fn_filter,
      const char *          fn_filter_arg,
      GCompareFunc          compare_func,
      Dir_Foreach_Func      func,
      void *                accumulator,
      int                   depth);

void dir_filtered_ordered_foreach(
      const char *          dirname,
      Dir_Filter_Func       dir_filter,
      GCompareFunc          compare_func,
      Dir_Foreach_Func      func,
      void *                accumulator,
      int                   depth);


/** Signature of function called by #dir_foreach_terminatable to process each file. */
typedef bool (*Terminating_Dir_Foreach_Func)(
      const char *  dirname,
      const char *  fn,
      void *        accumulator,
      int           depth);

void dir_foreach_terminatable(
      const char *          dirname,
      Filename_Filter_Func  fn_filter,
      Terminating_Dir_Foreach_Func      func,
      void *                accumulator,
      int                   depth);


void filter_and_limit_g_ptr_array(
      GPtrArray * line_array,
      char **     filter_terms,
      bool        ignore_case,
      int         limit,
      bool        free_strings);

void filter_and_limit_g_ptr_array2(
      GPtrArray * line_array,
      char **     filter_terms,
      bool        ignore_case,
      int         limit);

int read_file_with_filter(
      GPtrArray *  line_array,
      const char * fn,
      char **      filter_terms,
      bool         ignore_case,
      int          limit,
      bool         free_strings);

int rek_mkdir(
      const char * path,
      FILE *       ferr);

int fopen_mkdir(
      const char * path,
      const char * mode,
      FILE *       ferr,
      FILE **      fp_loc);

long get_inode_by_fn(const char * fqfn);

long get_inode_by_fd(int fd);


#endif /* FILE_UTIL_H_ */
