/*************************************************************************************************
 * dptsv
 *                                                       Copyright(c) 2000-2003 Mikio Hirabayashi
 *************************************************************************************************/


#include <depot.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#undef TRUE
#define TRUE           1                 /* boolean true */
#undef FALSE
#define FALSE          0                 /* boolean false */


/* global variables */
const char *progname;                    /* program name */


/* function prototypes */
int main(int argc, char **argv);
void usage(void);
int runimport(int argc, char **argv);
int runexport(int argc, char **argv);
void pdperror(const char *name);
char *getl(void);
int doimport(const char *name, int bnum);
int doexport(const char *name);


/* main routine */
int main(int argc, char **argv){
  int rv;
  progname = argv[0];
  if(argc < 2) usage();
  rv = 0;
  if(!strcmp(argv[1], "import")){
    rv = runimport(argc, argv);
  } else if(!strcmp(argv[1], "export")){
    rv = runexport(argc, argv);
  } else {
    usage();
  }
  return rv;
}


/* print the usage and exit */
void usage(void){
  fprintf(stderr, "%s: mutual converter between TSV and Depot database\n", progname);
  fprintf(stderr, "\n");
  fprintf(stderr, "usage:\n");
  fprintf(stderr, "  %s import [-bnum num] name\n", progname);
  fprintf(stderr, "  %s export name\n", progname);
  exit(1);
}


/* parse arguments of import command  */
int runimport(int argc, char **argv){
  char *name;
  int i, bnum, rv;
  name = NULL;
  bnum = -1;
  for(i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      if(!strcmp(argv[i], "-bnum")){
        if(++i >= argc) usage();
        bnum = atoi(argv[i]);
      } else {
        usage();
      }
    } else if(!name){
      name = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  rv = doimport(name, bnum);
  return rv;
}


/* parse arguments of export command  */
int runexport(int argc, char **argv){
  char *name;
  int i, rv;
  name = NULL;
  for(i = 2; i < argc; i++){
    if(!name && argv[i][0] == '-'){
      usage();
    } else if(!name){
      name = argv[i];
    } else {
      usage();
    }
  }
  if(!name) usage();
  rv = doexport(name);
  return rv;
}


/* print an error message */
void pdperror(const char *name){
  fprintf(stderr, "%s: %s: %s\n", progname, name, dperrmsg(dpecode));
}


/* read a line */
char *getl(void){
  char *buf;
  int c, len, blen;
  buf = NULL;
  len = 0;
  blen = 256;
  while((c = getchar()) != EOF){
    if(blen <= len) blen *= 2;
    if(!(buf = realloc(buf, blen + 1))){
      fprintf(stderr, "out of memory\n");
      exit(1);
    }
    if(c == '\n') c = '\0';
    buf[len++] = c;
    if(c == '\0') break;
  }
  if(!buf) return NULL;
  buf[len] = '\0';
  return buf;
}


/* perform import command */
int doimport(const char *name, int bnum){
  DEPOT *depot;
  char *buf, *key, *val;
  int i, err;
  /* open a database */
  if(!(depot = dpopen(name, DP_OWRITER | DP_OCREAT, bnum))){
    pdperror(name);
    return 1;
  }
  /* loop for each line */
  err = FALSE;
  for(i = 1; (buf = getl()) != NULL; i++){
    key = buf;
    if((val = strchr(buf, '\t')) != NULL){
      *val = '\0';
      val++;
      /* store a record */
      if(!dpput(depot, key, -1, val, -1, DP_DOVER)){
        pdperror(name);
        err = TRUE;
        break;
      }
    } else {
      fprintf(stderr, "%s: %s: invalid format in line %d\n", progname, name, i);
    }
    free(buf);
    if(err) break;
  }
  /* close the database */
  if(!dpclose(depot)){
    pdperror(name);
    return 1;
  }
  return err ? 1 : 0;
}


/* perform export command */
int doexport(const char *name){
  DEPOT *depot;
  char *key, *val;
  /* open a database */
  if(!(depot = dpopen(name, DP_OREADER, -1))){
    pdperror(name);
    return 1;
  }
  /* initialize the iterator */
  dpiterinit(depot);
  /* loop for each key */
  while((key = dpiternext(depot, NULL)) != NULL){
    /* retrieve a value with a key */
    val = dpget(depot, key, -1, 0, -1, NULL);
    if(key && val) printf("%s\t%s\n", key, val);
    free(val);
    free(key);
  }
  /* close the database */
  if(!dpclose(depot)){
    pdperror(name);
    return 1;
  }
  return 0;
}



/* END OF FILE */
