/* $Id: addrbookdb.cpp,v 1.6 2004/01/02 03:54:01 fesnel Exp $ */
/*******************************************************************************
 *   This program is part of a library used by the Archimedes email client     * 
 *                                                                             *
 *   Copyright : (C) 1995-1998 Gennady B. Sorokopud (gena@NetVision.net.il)    *
 *               (C) 1995 Ugen. J. S. Antsilevich (ugen@latte.worldbank.org)   *
 *               (C) 1998-2004 by the Archimedes Project                       *
 *                   http://sourceforge.net/projects/archimedes                *
 *                                                                             *
 *             --------------------------------------------                    *
 *                                                                             *
 *   This program is free software; you can redistribute it and/or modify      *
 *   it under the terms of the GNU Library General Public License as published *
 *   by the Free Software Foundation; either version 2 of the License, or      *
 *   (at your option) any later version.                                       *
 *                                                                             *
 *   This program is distributed in the hope that it will be useful,           *
 *   but WITHOUT ANY WARRANTY, without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
 *   GNU Library General Public License for more details.                      *
 *                                                                             *
 *   You should have received a copy of the GNU Library General Public License *
 *   along with this program; if not, write to the Free Software               *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA.  *
 *                                                                             *
 ******************************************************************************/

#include <string>
#include <list>

using namespace std;

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <limits.h>
#include <string.h>

#include "config.h"
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# if HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif

#include "addrbookdb.h"

/****************
 * AddressBookDB
 ****************/

AddressBookDB::~AddressBookDB()
{

	Clear();
}

bool
AddressBookDB::AddBook(AddressBook *book)
{
	iterator p;

    if (book == NULL)
		return false;

    /* check for an existing book */
    if (FindBook(book->GetName()) != NULL)
		return false;

	for (p = begin(); p != end() && book->GetName() > (*p)->GetName(); p++);

	insert(p, book);
    return true;
}

bool
AddressBookDB::NewBook(string name)
{
	AddressBook *book;
	iterator p;

    if (name.length() == 0)
		return false;

    if (FindBook(name) != NULL)
		return false;

	book = new AddressBook(name);
	for (p = begin(); p != end() && book->GetName() > (*p)->GetName(); p++);

	insert(p, book);
    return true;
}

bool
AddressBookDB::DeleteBook(string name)
{
    iterator p;

    for (p = begin(); p != end(); p++)
		if ((*p)->GetName() == name) {
			delete *p;
			erase(p);
			return true;
		}

    return false;
}

void
AddressBookDB::DeleteBookFile(const char *configdir, string name)
{
	string bookfile = string(configdir) + string("/.xfbook.") + name;

	unlink(bookfile.c_str());
}

AddressBook *
AddressBookDB::FindBook(string name)
{
    iterator p;

    for (p = begin(); p != end(); p++)
		if ((*p)->GetName() == name)
			return (*p);

    return NULL;
}

AddressBookEntry *
AddressBookDB::FindEntry(const char *addr)
{
    AddressBookEntry *entry = NULL;
    iterator p;

    for (p = begin(); p != end(); p++)
		if ((entry = (*p)->FindEntry(addr)) != NULL)
			break;

    return entry;
}

AddressBookEntry *
AddressBookDB::FindEntry(struct _mail_addr *addr)
{
    AddressBookEntry *entry = NULL;
    iterator p;

    for (p = begin(); p != end(); p++)
		if ((entry = (*p)->FindEntry(addr)) != NULL)
			break;

    return entry;
}

bool
AddressBookDB::Load(const char *configdir)
{
	const char *p;
	DIR *dir;
	struct dirent entry, *result;
	char buf[PATH_MAX];

	/* Search for files that match: configdir/.xfbook(\..+|) */
	dir = opendir(configdir);
	if (dir == NULL)
		return false;
#ifdef HAVE_READDIR_R
	while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
#else
	while ( (result = readdir(dir)) != NULL) {
#endif
		if (NAMLEN(result) > 8 && strncmp(result->d_name, ".xfbook.", 8) == 0) {
			strncpy(buf, result->d_name, NAMLEN(result));
			buf[NAMLEN(result)] = '\0';
			p = buf + 7;
						
			if (strcmp(p, ".default") == 0)
				continue;
			else if (strlen(p) > 1 && *p == '.') {
				if (!NewBook(++p))
					continue;

				FindBook(p)->Load(configdir);
								
			}
		}
	}
	closedir(dir);
		
	/* Read in the default address book */
	NewBook("default");
	FindBook("default")->Load(configdir);

	return true;
}

bool
AddressBookDB::Save(const char *configdir)
{
    iterator p;
    bool ret = true;

    for (p = begin(); p != end(); p++)
		if (!(*p)->Save(configdir))
			ret = false;

    return ret;
}

void
AddressBookDB::Clear()
{
	iterator p;

	for (p = begin(); size() > 0;) {
		delete *p;
		p = erase(p);
	}
}
