#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <ndb.h>
#include "ndbhf.h"

static Ndb*	doopen(char*, char*);
static void	hffree(Ndb*);

static char *deffile = "#9/ndb/local";

/*
 *  the database entry in 'file' indicates the list of files
 *  that makeup the database.  Open each one and search in
 *  the same order.
 */
Ndb*
ndbopen(char *file)
{
	Ndb *db, *first, *last;
	Ndbs s;
	Ndbtuple *t, *nt;

	if(file == 0)
		file = unsharp(deffile);
	db = doopen(file, nil);
	if(db == 0)
		return 0;
	first = last = db;
	t = ndbsearch(db, &s, "database", "");
	Bseek(&db->b, 0, 0);
	if(t == 0)
		return db;
	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "file") != 0)
			continue;
		if(strcmp(nt->val, file) == 0){
			/* default file can be reordered in the list */
			if(first->next == 0)
				continue;
			if(strcmp(first->file, file) == 0){
				db = first;
				first = first->next;
				last->next = db;
				db->next = 0;
				last = db;
			}
			continue;
		}
		db = doopen(nt->val, file);
		if(db == 0)
			continue;
		last->next = db;
		last = db;
	}
	ndbfree(t);
	return first;
}

/*
 *  open a single file
 */
static Ndb*
doopen(char *file, char *rel)
{
	char *p;
	Ndb *db;

	db = (Ndb*)malloc(sizeof(Ndb));
	if(db == 0)
		return 0;

	memset(db, 0, sizeof(Ndb));
	/*
	 * Rooted paths are taken as is.
	 * Unrooted paths are taken relative to db we opened.
	 */
	if(file[0]!='/' && rel && (p=strrchr(rel, '/'))!=nil)
		snprint(db->file, sizeof(db->file), "%.*s/%s", 
			utfnlen(rel, p-rel), rel, file);
	else
		strncpy(db->file, file, sizeof(db->file)-1);

	if(ndbreopen(db) < 0){
		free(db);
		return 0;
	}

	return db;
}

/*
 *  dump any cached information, forget the hash tables, and reopen a single file
 */
int
ndbreopen(Ndb *db)
{
	int fd;
	Dir *d;

	/* forget what we know about the open files */
	if(db->mtime){
		_ndbcacheflush(db);
		hffree(db);
		close(Bfildes(&db->b));
		Bterm(&db->b);
		db->mtime = 0;
	}

	/* try the open again */
	fd = open(db->file, OREAD);
	if(fd < 0)
		return -1;
	d = dirfstat(fd);
	if(d == nil){
		close(fd);
		return -1;
	}

	db->qid = d->qid;
	db->mtime = d->mtime;
	db->length = d->length;
	Binit(&db->b, fd, OREAD);
	free(d);
	return 0;
}

/*
 *  close the database files
 */
void
ndbclose(Ndb *db)
{
	Ndb *nextdb;

	for(; db; db = nextdb){
		nextdb = db->next;
		_ndbcacheflush(db);
		hffree(db);
		close(Bfildes(&db->b));
		Bterm(&db->b);
		free(db);
	}
}

/*
 *  free the hash files belonging to a db
 */
static void
hffree(Ndb *db)
{
	Ndbhf *hf, *next;

	for(hf = db->hf; hf; hf = next){
		next = hf->next;
		close(hf->fd);
		free(hf);
	}
	db->hf = 0;
}

/*
 *  return true if any part of the database has changed
 */
int
ndbchanged(Ndb *db)
{
	Ndb *ndb;
	Dir *d;

	for(ndb = db; ndb != nil; ndb = ndb->next){
		d = dirfstat(Bfildes(&db->b));
		if(d == nil)
			continue;
		if(ndb->qid.path != d->qid.path
		|| ndb->qid.vers != d->qid.vers){
			free(d);
			return 1;
		}
		free(d);
	}
	return 0;
}
