/* various tests. */

#include <stdio.h>
#include <sys/stat.h>           /* S_...(), S_... */
#include <dlfcn.h>              /* dl...() */
#include <string.h>             /* str...() */
#include <ctype.h>
#include <stdlib.h>             /* exit(), free() */

#include "file_fun.h"
#include "util.h"
#include "alert.h"



int                      debug=1;

static void             *lib=NULL;
static struct _file_fun  ff;
/* static char             *fmt[]={ "DIR", "FILE" }; */

char                    *home=NULL,
                        *temp=NULL;



#include "setup.h"
#include "cache.h"

int file_monitor_remove_all(void *ns) { return NOIR_IGNORED; }

int selection_remove(void *ns,char *x) { return NOIR_IGNORED; }
char *noir_sess_get_cwd(noir_sess *ns) { return NULL; }
char *noir_sess_get_selection(noir_sess *ns) { return NULL; }



#if 1

int thumbnail_enqueue(file_info *fi) { return NOIR_FAIL; }
file_info *thumbnailer_pending(void) { return NULL; }

int       form_alert(noir_sess *ns,char *msg,...) {
  E(0,"(,\"%s\")\n",msg);
  return NOIR_IGNORED; }

int       form_dial(noir_sess *ns,alert_type at,alert_buttons ab,char *msg,char *buttons) {
  E(0,"(,%d,%d,\"%s\",\"%s\")\n",at,ab,msg,buttons);
  return NOIR_NOTSUPP; }

void      form_file_ask(char *op,char **t) {
  E(0,"(\"%s\",)\n",op); }

int       form_yes_no(noir_sess *ns,char *msg) {
  E(0,"(,\"%s\")\n",msg);
  return 0; }

#else
void      form_stock(noir_sess *,alert_stock);
void      form_file(noir_sess *,char *);
#endif



/*****************************************************************************/



int my_file_init(char *fn) {
  const char *err;
  int         ret;

  memset(&ff,0,sizeof(struct _file_fun));

  ret=dlmulti("file-system backend",fn,RTLD_NOW,&lib,
              "!backend_activate !backend_getdir "
              "!backend_opendir !backend_readdir !backend_closedir "
              "!backend_init !backend_exit "
              "!backend_exists !backend_get_info !backend_get_meta "
              "!backend_set_meta !backend_get_mime "
              "!backend_monitor_add !backend_monitor_remove "
              "!backend_cp !backend_hardlink !backend_symlink "
              "!backend_mv !backend_rm "
              "!backend_rmdir !backend_mkdir "
              "!backend_mime_handler_get !backend_mime_handler_set "
              "?backend_readlink",
              &ff.file_activate,&ff.file_getdir,
              &ff.file_opendir,&ff.file_readdir,&ff.file_closedir,
              &ff.file_init,&ff.file_exit,
              &ff.file_exists,&ff.file_get_info,&ff.file_get_meta,
              &ff.file_set_meta,&ff.file_get_mime,
              &ff.file_m_add,&ff.file_m_rem,
              &ff.file_cp,&ff.file_hardlink,&ff.file_symlink,
              &ff.file_mv,&ff.file_rm,
              &ff.file_rmdir,&ff.file_mkdir,
              &ff.file_mime_handler_get,&ff.file_mime_handler_set,
              &ff.file_readlink);
  if((ret!=NOIR_SUCC)&&(ret!=NOIR_PARTIAL)) {
    if(ret==NOIR_NOTFOUND) {
      E(0,"\"%s\" is not a valid backend!  STOP.\n",fn);
      goto fail; }
    else {
      if(!(err=dlerror()))
        err="???";
      E(0,"failed to load \"%s\": %s\n",fn,err);
      goto fail; }}

  ff.file_init(NULL);  /* FIXME ### */

#if 0
  { size_t l=strlen(path_setup)+sizeof(DIR_CACHE)+1;
    char *dir=malloc(l);
    if(dir) {
      snprintf(dir,l,"%s/" DIR_CACHE,path_setup);
      file_mkdir(dir,S_IRWXU,TRUE);
      free(dir); }}
#endif

  return ret;

  fail:
/* return NOIR_META_DLFAIL; */
  exit(1); }



/*****************************************************************************/



int test_load_backend(char *be) {
  int ret;

  if(!be) {
    E(0,"must give backend as first parameter\n");
    return NOIR_NODATA; }

  ret=my_file_init(be);

  switch(ret) {
    case NOIR_SUCC:
      E(1,"%s contains complete set of functions\n",be);
      break;
    case NOIR_PARTIAL:
      E(1,"%s contains basic set of functions\n",be);
      break;
    default:
      E(0,"%s could not be loaded (code #%d)\n",be,(ret<0)?-ret:ret); }
  return ret; }



/*****************************************************************************/



int test_do_cmd(char *cmd,int argc,char **argv) {
  int   c,l=0;
  char *u=NULL,*p,*last=NULL,*first=NULL;

  for(p=cmd;*p;p++)
    *p=tolower(*p);

  for(c=0;c<(argc-1);c++)
    l+=strlen(argv[c])+3;

  if(!(u=malloc(l+1)))
    return NOIR_OOM;

  p=u;
  for(c=0;c<(argc-1);c++) {
    l=strlen(argv[c])+3;
    snprintf(p,l+1,"\"%s\" ",argv[c]);
    p+=l; }
  *(--p)='\0';

  if(argc) {
    first=argv[argc-1];
    if(argc>1)
      last=argv[argc-1];
    E(0,"%s %s \"%s\"\n",cmd,u,last); }

#if 0
  int   (*file_mv)(char *,char *);
  int   (*file_cp)(char *,char *);
  int   (*file_rm)(char *);
  int   (*file_mkdir)(char *,int,int);
  int   (*file_rmdir)(char *);
  int   (*file_symlink)(char *,char *);
  int   (*file_hardlink)(char *,char *);
#endif

  free(u);

  return NOIR_SUCC; }



/*****************************************************************************/



int main(int argc,char **argv) {
  int   ret=0;
  char *be=(argc>1)?argv[1]:NULL,*cmd=(argc>2)?argv[2]:NULL;

  memset(&ff,0,sizeof(ff));

  paths_init(NULL,NULL,argv[0]);

  if(((ret=test_load_backend(be))==NOIR_SUCC)||(ret==NOIR_PARTIAL)) {
    if(cmd)
      ret=test_do_cmd(cmd,argc-3,&argv[3]);
    E(1,"  shutting down: %d\n",ff.file_exit()); }

  paths_exit();

  return ret; }


#if 0
  int   (*file_get_info)(noir_sess *,char *,file_info **);
  int   (*file_get_meta)(noir_sess *,char *,meta **md);
  int   (*file_set_meta)(noir_sess *,char *,meta **md,meta *r);

  dir_entry *(*file_getdir)(char *,fdg_flags);
  void *(*file_opendir)(char *path);
  int   (*file_readdir)(void **data,char *dir_name);
  int   (*file_closedir)(void **data);

  char *(*file_mime_handler_get)(const char *mime,char **);
  int   (*file_mime_handler_set)(char *mime,char *handler);
  char *(*file_get_mime)(char *);

  char *(*file_readlink)(char *);

  int   (*file_exists)(char *);

  int   (*file_activate)(char *,char *);

  int   (*file_m_add)(noir_sess *,noir_file_monitor,char *);
  int   (*file_m_rem)(noir_sess *,void *);

  int   (*file_init)(noir_sess *);
  int   (*file_exit)(noir_sess *); };
#endif



/*****************************************************************************/
