#ifndef _COOKIE_MANAGER_H
#define _COOKIE_MANAGER_H

#include <stdio.h>
#include <Locker.h>
#include <String.h>
#include <time.h>
#include <posix/limits.h>
#include "Timer.h"
#include "Queue.h"
#include "URL.h"
#include "util.h"
#include "Binder.h"

const uint kCookieHashSize = 389;

class Cookie;

class CookieManager {
public:
	CookieManager();
	~CookieManager();
	void ParseCookieString(const Wagner::URL&, const char *cookieString, time_t serverdate = -1);
	void BuildCookieString(const Wagner::URL&, char *outString, size_t size);
	void BuildCookieString(const Wagner::URL&, StringBuffer&);
	void SetCookie(const Wagner::URL &src, const char *name, const char *value,
		const char *domain = "", const char *path = "", time_t expiration = -1);
	void GetCookieValue(const Wagner::URL &requestingResource, const char *name,
		char *outValue, size_t valueSize);
		
	void DumpCookies();
#if ENABLE_LOG
	void GetUserInfo(BString* into);
#endif
	
private:
	void AddCookie(Cookie *cookie);
	void DeleteCookie(Cookie *cookie);
	void ReadCookieFile();
	void WriteCookieFile();
	void Clear();
	void CreateCookieFileName();
	static void UpdateHook(const BMessage *data);
	unsigned HashDomain(const char *host);
	
	BinderNode::observer_token fObserverToken;
	BinderNode::property fNodeProperty;
	BString fCurrentUser;
	BLocker fLock;
	bool fFileOpened;
	Queue fLRU;
	int32 fNumCookies;
	Cookie *fDomainHash[kCookieHashSize];
	Cookie *fNameHash[kCookieHashSize];
	Wagner::Timer fUpdateFileTimer;
	bool fDirty;
	char fCookieFilePath[PATH_MAX];
	
	friend status_t UserObserverHook(void *userData, uint32 observed, void *extraData);
};

extern CookieManager cookieManager;

#endif
