#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>

#include "indexl.h"


int
dict_close(Dict *d) {

  int i=1;

  if (!z_close(&d->z))
    i=0;
  if (!words_close(&d->w))
    i=0;
  if (!files_close(&d->f))
    i=0;

  return i;

}

static INLINE int
dict_build(Dict *d) {

  if (!words_build_wordlist(&d->f,&d->w))
    return 0;
  
  inf("building ...");
  if (!huff_build_from_freq(&d->w))
    return 0;
  
  inf("coding ...");
  if (!huff_load_codes(&d->w))
    return 0;
  
  inf("testing ...");
  if (!huff_test(&d->w))
    return 0;
  
  inf("done\n");
  
  if (!z_encode_files(d))
    return 0;
  
  if (!hash_perf(&d->w.d,1000000))
    return 0;
  if (!hash_opt(&d->w.d))
    return 0;
  if (!hash_perf(&d->w.d,1000000)) 
    return 0;
  if (!hash_perf(&d->w.d,1000000)) 
    return 0;
  if (!hash_perf(&d->w.d,1000000)) 
    return 0;

  return 1;

}


int
dict_open(Dict *d,const char *s,int new) {

  char *bb,q;
  const char *c;
  Map b={0};
  unsigned k;
  struct stat ss;

  if (!s) {
    err("Bad directory: %s\n",s);
    return 0;
  }

  if (!*s || stat(s,&ss) || !(ss.st_mode & S_IFDIR) || chdir(s)) {
    err("Bad directory: %s\n",s);
    return 0;
  }

  k=strlen(s);
  map_write(&b,s,k);
  q='/';
  if (s[k-1]!=q)
    map_write_element(&b,q);
  q=0;
  map_write_element(&b,q);
  for (bb=b.m1;(bb=strchr(bb,'/'));) *bb='-';

  c=map_temp_str(".%s",b.m1);
  if (stat(c,&ss)) {

    int l;

    if ((l=open(c,O_CREAT,0700))==-1) {
      err("Can't open %s\n",c);
      return 0;
    }
    new=1;

  }

  if (!z_open(&d->z,b.m1,new))
    return 0;

  if (!words_open(&d->w,b.m1,new))
    return 0;

  if (!files_open(&d->f,b.m1,s,new))
    return 0;
  
  map_close(&b);

  if (new) {

    if (!dict_build(d))
      return 0;

    if (!dict_close(d))
      return 0;

    if (!dict_open(d,s,0))
      return 0;

  }

  return 1;

}

